Skip to content

Instantly share code, notes, and snippets.

@minoki
Created December 15, 2021 03:40
Show Gist options
  • Save minoki/df8fa5335f071cd8222eb8f61ed7517e to your computer and use it in GitHub Desktop.
Save minoki/df8fa5335f071cd8222eb8f61ed7517e to your computer and use it in GitHub Desktop.
Standard ML on LuaTeX: math formula
\documentclass{article}
\usepackage{amsmath}
\usepackage{luacode}
\begin{document}
\begin{luacode*}
local M = require "expr"
function diff(expr, var)
local result = M.parse(expr)
if result.tag == "Ok" then
local e = M.simplify(M.diff(var)(result.payload))
tex.print(M.toTeXString(e))
else
tex.print("\\text{Failed to parse:"..result.payload.."}")
end
end
\end{luacode*}
\[\mathrm{diff}(\sin(2x+1),x)=\directlua{diff("sin(2*x+1)","x")}\]
\end{document}
local assert = assert
local error = error
local getmetatable = getmetatable
local pairs = pairs
local pcall = pcall
local setmetatable = setmetatable
local math = math
local math_abs = math.abs
local math_type = math.type
local math_maxinteger = math.maxinteger
local math_mininteger = math.mininteger
local math_ult = math.ult
local string = string
local string_format = string.format
local table = table
local table_pack = table.pack
local table_unpack = table.unpack
local function _Unit_EQUAL(t)
return true
end
local function _Record_EQUAL(fields)
return function(t)
local a, b = t[1], t[2]
for k,eq in pairs(fields) do
if not eq({a[k], b[k]}) then
return false
end
end
return true
end
end
local function _EQUAL(t)
return t[1] == t[2]
end
local function _id(x)
return x
end
local _exn_meta = {}
function _exn_meta:__tostring()
local traceback = self.traceback
if traceback then
traceback = "\n" .. traceback
else
traceback = ""
end
return string_format("%s: %s%s", self.location or "<no location info>", self.tag[1], traceback)
end
local _Match_tag = { "Match" }
local _Match = setmetatable({ tag = _Match_tag }, _exn_meta)
local _Bind_tag = { "Bind" }
local _Bind = setmetatable({ tag = _Bind_tag }, _exn_meta)
local _Overflow_tag = { "Overflow" }
local _Overflow = setmetatable({ tag = _Overflow_tag }, _exn_meta)
local _Div_tag = { "Div" }
local _Div = setmetatable({ tag = _Div_tag }, _exn_meta)
local _Size_tag = { "Size" }
local _Size = setmetatable({ tag = _Size_tag }, _exn_meta)
local _Subscript_tag = { "Subscript" }
local _Subscript = setmetatable({ tag = _Subscript_tag }, _exn_meta)
local _Fail_tag = { "Fail" }
local function _Fail(message)
return setmetatable({ tag = _Fail_tag, payload = message }, _exn_meta)
end
local function __exn_instanceof(e, tag)
return getmetatable(e) == _exn_meta and e.tag == tag
end
local function _raise(x, location)
local traceback = debug.traceback(nil, 2)
local e = setmetatable({ tag = x.tag, payload = x.payload, location = location, traceback = traceback }, _exn_meta)
error(e, 1)
end
-- Int
local function __Int_add(x, y)
-- assert(math_type(x) == "integer")
-- assert(math_type(y) == "integer")
local z = x + y
if y > 0 and z < x then
_raise(_Overflow, "Int.+")
elseif y < 0 and z > x then
_raise(_Overflow, "Int.+")
else
return z
end
end
local function __Int_sub(x, y)
-- assert(math_type(x) == "integer")
-- assert(math_type(y) == "integer")
local z = x - y
if y < 0 and z < x then
_raise(_Overflow, "Int.-")
elseif y > 0 and x < z then
_raise(_Overflow, "Int.-")
else
return z
end
end
local function __Int_mul(x, y)
-- assert(math_type(x) == "integer")
-- assert(math_type(y) == "integer")
local z = x * y
if (x ~= 0 and z // x ~= y) or (y ~= 0 and z // y ~= x) then
_raise(_Overflow, "Int.*")
else
return z
end
end
local function __Int_div(x, y)
-- assert(math_type(x) == "integer")
-- assert(math_type(y) == "integer")
if y == 0 then
_raise(_Div, "Int.div")
elseif x == math_mininteger and y == -1 then
_raise(_Overflow, "Int.div")
end
return x // y
end
local function __Int_mod(x, y)
-- assert(math_type(x) == "integer")
-- assert(math_type(y) == "integer")
if y == 0 then
_raise(_Div, "Int.mod")
end
return x % y
end
local function _Int_negate(x)
-- assert(math_type(x) == "integer")
if x == math_mininteger then
_raise(_Overflow, "Int.~")
end
return - x
end
local function _Int_abs(x)
-- assert(math_type(x) == "integer")
if x == math_mininteger then
_raise(_Overflow, "Int.abs")
end
return math_abs(x)
end
-- Word
local function __Word_div(x, y)
-- assert(math_type(x) == "integer")
-- assert(math_type(y) == "integer")
if y == 0 then
_raise(_Div, "Word.div")
elseif y > 0 then
if x >= 0 then
return x // y
else -- x < 0
-- Algorithm from Programming in Lua, 4th ed.
local q = ((x >> 1) // y) << 1
local r = x - q * y
if math_ult(r, y) then
return q
else
return q + 1
end
end
else -- y < 0
if math_ult(x, y) then
return 0
else
return 1
end
end
end
local function __Word_mod(x, y)
-- assert(math_type(x) == "integer")
-- assert(math_type(y) == "integer")
if y == 0 then
_raise(_Div, "Word.mod")
elseif y > 0 then
if x >= 0 then
return x % y
else -- x < 0
local q = ((x >> 1) // y) << 1
local r = x - q * y
if math_ult(r, y) then
return r
else
return r - y
end
end
else -- y < 0
if math_ult(x, y) then
return x
else
return x - y
end
end
end
local __Word_LT = math_ult
-- List
local _nil = { tag = "nil" }
local function _cons(t)
return { tag = "::", payload = t }
end
local function _List_EQUAL(eq)
local function go(a, b)
local at, bt = a.tag, b.tag
if at ~= bt then
return false
elseif at == "nil" then
return true
elseif eq({a.payload[1], b.payload[1]}) then
return go(a.payload[2], b.payload[2])
else
return false
end
end
return function(t)
return go(t[1], t[2])
end
end
local function _list(t)
local xs = _nil
for i = t.n, 1, -1 do
xs = { tag = "::", payload = { t[i], xs } }
end
return xs
end
-- Ref
local function _ref(x)
return { tag = "ref", payload = x }
end
-- Array
local function _Array_array(t)
local n, init = t[1], t[2]
if n < 0 then -- or maxLen < n
_raise(_Size, "Array.array")
end
local t = { n = n }
for i = 1, n do
t[i] = init
end
return t
end
local function _VectorOrArray_fromList(xs)
local t = {}
local n = 0
while xs.tag == "::" do
n = n + 1
t[n] = xs.payload[1]
xs = xs.payload[2]
end
t.n = n
return t
end
local function _VectorOrArray_tabulate(t)
local n, f = t[1], t[2]
if n < 0 then -- or maxLen < n
_raise(_Size, "(Vector|Array).tabulate")
end
local t = { n = n }
for i = 1, n do
t[i] = f(i - 1)
end
return t
end
-- Vector
local function _Vector_EQUAL(eq)
local function go(a, b)
local n = a.n
if n ~= b.n then
return false
end
for i = 1, n do
if not eq({a[i], b[i]}) then
return false
end
end
return true
end
return function(t)
return go(t[1], t[2])
end
end
local function _Vector_concat(xs)
local n = 0
local t = {}
while xs.tag == "::" do
local p = xs.payload
local u = p[1]
local m = u.n
for i = 1,m do
t[n + i] = u[i]
end
n = n + m
xs = p[2]
end
t.n = n
return t
end
-- Lua interface
local function _Lua_global(name)
return _ENV[name]
end
local function _Lua_call(f)
return function(v)
return table_pack(f(table_unpack(v, 1, v.n)))
end
end
local function _Lua_method(t)
local self, name = t[1], t[2]
return function(v)
return table_pack(self[name](self, table_unpack(v, 1, v.n)))
end
end
local function _Lua_newTable()
return {}
end
local function _Lua_function(f)
return function(...)
local r = f(table_pack(...))
return table_unpack(r, 1, r.n)
end
end
local NONE_386 = { tag = "NONE" }
local function SOME_385(x)
return { tag = "SOME", payload = x }
end
local sub_547 = function(a_548)
local vec_550 = a_548[1]
local tmp_10989 = 0
local x_4119 = a_548[2]
local tmp0
if x_4119 < tmp_10989 then
tmp0 = true
else
local tmp_10990
do
local a_4128 = vec_550
tmp_10990 = a_4128.n
end
local y_4124 = a_548[2]
tmp0 = tmp_10990 <= y_4124
end
if tmp0 then
_raise(_Subscript, "mlbasis.sml:113:24")
else
local vec_4137 = a_548[1]
local i_4138 = a_548[2]
return vec_4137[i_4138 + 1]
end
end
local byte_681, char_682, concat_688, gsub_684, match_685, sub_686, tostring_676
do
tostring_676 = _Lua_global("tostring")
do
local tmp_10998 = "byte"
local t_4188 = string
local a_4190
do
local x_4193 = tmp_10998
local tmp_11000 = x_4193
a_4190 = {t_4188, tmp_11000}
end
local t_4195 = a_4190[1]
local k_4196 = a_4190[2]
byte_681 = t_4195[k_4196]
local tmp_11001 = "char"
local t_4199 = string
local a_4201
do
local x_4204 = tmp_11001
local tmp_11003 = x_4204
a_4201 = {t_4199, tmp_11003}
end
local t_4206 = a_4201[1]
local k_4207 = a_4201[2]
char_682 = t_4206[k_4207]
local tmp_11007 = "gsub"
local t_4221 = string
local a_4223
do
local x_4226 = tmp_11007
local tmp_11009 = x_4226
a_4223 = {t_4221, tmp_11009}
end
local t_4228 = a_4223[1]
local k_4229 = a_4223[2]
gsub_684 = t_4228[k_4229]
local tmp_11010 = "match"
local t_4232 = string
local a_4234
do
local x_4237 = tmp_11010
local tmp_11012 = x_4237
a_4234 = {t_4232, tmp_11012}
end
local t_4239 = a_4234[1]
local k_4240 = a_4234[2]
match_685 = t_4239[k_4240]
local tmp_11013 = "sub"
local t_4243 = string
local a_4245
do
local x_4248 = tmp_11013
local tmp_11015 = x_4248
a_4245 = {t_4243, tmp_11015}
end
local t_4250 = a_4245[1]
local k_4251 = a_4245[2]
sub_686 = t_4250[k_4251]
end
local tmp_11016 = "concat"
local t_4254 = table
local a_4256
do
local x_4259 = tmp_11016
local tmp_11018 = x_4259
a_4256 = {t_4254, tmp_11018}
end
local t_4261 = a_4256[1]
local k_4262 = a_4256[2]
concat_688 = t_4261[k_4262]
end
local Chr_883, EQUAL_892, GREATER_891, LESS_893
do
local Chr__tag_1817 = { "Chr" }
Chr_883 = setmetatable({ tag = Chr__tag_1817 }, _exn_meta)
LESS_893 = { tag = "LESS" }
EQUAL_892 = { tag = "EQUAL" }
GREATER_891 = { tag = "GREATER" }
end
do
local BIN_922 = { tag = "BIN" }
local OCT_921 = { tag = "OCT" }
local DEC_920 = { tag = "DEC" }
local HEX_919 = { tag = "HEX" }
local function SCI_926(x)
return { tag = "SCI", payload = x }
end
local function FIX_925(x)
return { tag = "FIX", payload = x }
end
local function GEN_924(x)
return { tag = "GEN", payload = x }
end
local EXACT_923 = { tag = "EXACT" }
end
local toString_992 = function(a_993)
local x_5016 = a_993
local result_995 = table_pack(tostring_676(x_5016))
local tmp1 = sub_547({result_995, 0})
local a_5017 = "-"
local x_5019 = a_5017
local a_5020 = "~"
local x_5022 = a_5020
local result_996 = table_pack(gsub_684(tmp1, x_5019, x_5022))
local a_5026 = sub_547({result_996, 0})
local x_5028 = a_5026
return x_5028
end
local computeWordSize_1008
computeWordSize_1008 = function(a_1009)
local x_1011 = a_1009[1]
local n_1010 = a_1009[2]
if x_1011 == 0 then
return n_1010
else
local a_5069
do
local a_5072
do
local a_5076 = x_1011
local x_5078 = a_5076
local tmp_11073 = x_5078
local a_5079 = 1
local x_5081 = a_5079
local tmp_11072 = x_5081
a_5072 = {tmp_11073, tmp_11072}
end
local x_5074 = a_5072[1]
local y_5075 = a_5072[2]
a_5069 = x_5074 >> y_5075
end
local x_5071 = a_5069
local tmp_11074 = 1
local x_5084 = a_1009[2]
local tmp2 = __Int_add(x_5084, tmp_11074)
return computeWordSize_1008({x_5071, tmp2})
end
end
local a_5089 = math_maxinteger
local x_5091 = a_5089
local wordSize_1007 = computeWordSize_1008({x_5091, 1})
local sub_1118 = function(a_1119)
local s_1121 = a_1119[1]
local tmp_11122 = 0
local x_5539 = a_1119[2]
local tmp3
if x_5539 < tmp_11122 then
tmp3 = true
else
local tmp_11123
do
local a_5545 = s_1121
tmp_11123 = #a_5545
end
local y_5544 = a_1119[2]
tmp3 = tmp_11123 <= y_5544
end
if tmp3 then
_raise(_Subscript, "mlbasis.sml:808:44")
else
local i_PRIME_1122
do
local tmp_11124 = 1
local x_5550 = a_1119[2]
i_PRIME_1122 = __Int_add(x_5550, tmp_11124)
end
local a_5552 = s_1121
local x_5554 = a_5552
local x_5557 = i_PRIME_1122
local x_5560 = i_PRIME_1122
local result_1123 = table_pack(sub_686(x_5554, x_5557, x_5560))
local a_5564 = sub_547({result_1123, 0})
local x_5566 = a_5564
return x_5566
end
end
local Substring_1832
do
local sub_1180 = function(a_1181)
local s_1185 = a_1181[1][1]
local tmp_11135 = 0
local y_5763 = a_1181[2]
local tmp4
if tmp_11135 <= y_5763 then
local x_5766 = a_1181[2]
local y_5767 = a_1181[1][3]
tmp4 = x_5766 < y_5767
else
tmp4 = false
end
if tmp4 then
local x_5770 = a_1181[1][2]
local y_5771 = a_1181[2]
local tmp5 = __Int_add(x_5770, y_5771)
return sub_1118({s_1185, tmp5})
else
_raise(_Subscript, "mlbasis.sml:872:30")
end
end
local full_1192 = function(a_1193)
return {a_1193, 0, #a_1193}
end
local getc_1195 = function(a_1196)
local s_1199 = a_1196[1]
local i_1198 = a_1196[2]
local z_1197 = a_1196[3]
if z_1197 == 0 then
return NONE_386
else
local tmp6 = sub_1118({s_1199, i_1198})
local tmp_11136 = 1
local x_5777 = a_1196[2]
local tmp7 = __Int_add(x_5777, tmp_11136)
local tmp_11137 = 1
local x_5781 = a_1196[3]
local tmp8 = __Int_sub(x_5781, tmp_11137)
return SOME_385({tmp6, {s_1199, tmp7, tmp8}})
end
end
local size_1202 = function(a_5789)
local z_5791 = a_5789[3]
return z_5791
end
local base_1201 = function(a_5792)
return a_5792
end
Substring_1832 = {["base"] = base_1201, ["full"] = full_1192, ["getc"] = getc_1195, ["size"] = size_1202, ["sub"] = sub_1180}
end
local isAlpha_1241, isAlphaNum_1242, isDigit_1244, isHexDigit_1246, isLower_1247, isSpace_1249, isUpper_1251, ord_1210, toString_1260
do
local x_5798 = byte_681
ord_1210 = x_5798
local chr_1211 = function(x_1212)
local tmp_11138 = 0
local tmp9
if x_1212 < tmp_11138 then
tmp9 = true
else
local tmp_11139 = 255
tmp9 = x_1212 > tmp_11139
end
if tmp9 then
_raise(Chr_883, "mlbasis.sml:922:37")
else
local x_5815 = x_1212
local tmp10 = table_pack(char_682(x_5815))
local a_5810 = sub_547({tmp10, 0})
local x_5812 = a_5810
return x_5812
end
end
local isPrint_1248
do
local a_5875 = "^[A-Za-z]$"
isAlpha_1241 = function(a_5876)
local a_5880
do
local x_5884 = a_5876
local x_5887 = a_5875
local tmp11 = table_pack(match_685(x_5884, x_5887))
local a_5881 = sub_547({tmp11, 0})
a_5880 = a_5881 == nil
end
return not a_5880
end
local a_5892 = "^[A-Za-z0-9]$"
isAlphaNum_1242 = function(a_5893)
local a_5897
do
local x_5901 = a_5893
local x_5904 = a_5892
local tmp12 = table_pack(match_685(x_5901, x_5904))
local a_5898 = sub_547({tmp12, 0})
a_5897 = a_5898 == nil
end
return not a_5897
end
local a_5926 = "^[0-9]$"
isDigit_1244 = function(a_5927)
local a_5931
do
local x_5935 = a_5927
local x_5938 = a_5926
local tmp13 = table_pack(match_685(x_5935, x_5938))
local a_5932 = sub_547({tmp13, 0})
a_5931 = a_5932 == nil
end
return not a_5931
end
local a_5960 = "^[A-Fa-f0-9]$"
isHexDigit_1246 = function(a_5961)
local a_5965
do
local x_5969 = a_5961
local x_5972 = a_5960
local tmp14 = table_pack(match_685(x_5969, x_5972))
local a_5966 = sub_547({tmp14, 0})
a_5965 = a_5966 == nil
end
return not a_5965
end
local a_5977 = "^[a-z]$"
isLower_1247 = function(a_5978)
local a_5982
do
local x_5986 = a_5978
local x_5989 = a_5977
local tmp15 = table_pack(match_685(x_5986, x_5989))
local a_5983 = sub_547({tmp15, 0})
a_5982 = a_5983 == nil
end
return not a_5982
end
local a_5994 = "^[^%c]$"
isPrint_1248 = function(a_5995)
local a_5999
do
local x_6003 = a_5995
local x_6006 = a_5994
local tmp16 = table_pack(match_685(x_6003, x_6006))
local a_6000 = sub_547({tmp16, 0})
a_5999 = a_6000 == nil
end
return not a_5999
end
local a_6011 = "^[ \n\t\r\v\f]$"
isSpace_1249 = function(a_6012)
local a_6016
do
local x_6020 = a_6012
local x_6023 = a_6011
local tmp17 = table_pack(match_685(x_6020, x_6023))
local a_6017 = sub_547({tmp17, 0})
a_6016 = a_6017 == nil
end
return not a_6016
end
local a_6045 = "^[A-Z]$"
isUpper_1251 = function(a_6046)
local a_6050
do
local x_6054 = a_6046
local x_6057 = a_6045
local tmp18 = table_pack(match_685(x_6054, x_6057))
local a_6051 = sub_547({tmp18, 0})
a_6050 = a_6051 == nil
end
return not a_6050
end
end
toString_1260 = function(a_1261)
if a_1261 == "\\" then
return "\\\\"
elseif a_1261 == "\"" then
return "\\\""
else
local tmp19 = isPrint_1248(a_1261)
if tmp19 then
local x_6096 = a_1261
return x_6096
elseif a_1261 == "\\a" then
return "\\a"
elseif a_1261 == "\\b" then
return "\\b"
elseif a_1261 == "\\t" then
return "\\t"
elseif a_1261 == "\\n" then
return "\\n"
elseif a_1261 == "\\v" then
return "\\v"
elseif a_1261 == "\\f" then
return "\\f"
elseif a_1261 == "\\r" then
return "\\r"
else
local x_1263 = ord_1210(a_1261)
local tmp_11154 = 32
if x_1263 < tmp_11154 then
local a_6101
do
local tmp_11157 = "\\^"
local tmp_11155 = 64
local tmp20 = __Int_add(x_1263, tmp_11155)
local a_6105 = chr_1211(tmp20)
local x_6107 = a_6105
local tmp_11156 = x_6107
a_6101 = {tmp_11157, tmp_11156}
end
local x_6103 = a_6101[1]
local y_6104 = a_6101[2]
return x_6103 .. y_6104
else
local tmp_11158 = 100
if x_1263 < tmp_11158 then
local tmp_11159, tmp_11160
do
tmp_11160 = "\\0"
tmp_11159 = toString_992(x_1263)
end
return tmp_11160 .. tmp_11159
else
local tmp_11161, tmp_11162
do
tmp_11162 = "\\"
tmp_11161 = toString_992(x_1263)
end
return tmp_11162 .. tmp_11161
end
end
end
end
end
end
local _AT_1282, exists_1401, foldl_1378, map_1334
do
_AT_1282 = function(a_1283)
if a_1283[1].tag == "nil" then
local ys_1284 = a_1283[2]
return ys_1284
elseif a_1283[1].tag == "::" then
local x_1287 = a_1283[1].payload[1]
local xs_1286 = a_1283[1].payload[2]
local ys_1285 = a_1283[2]
local tmp21 = _AT_1282({xs_1286, ys_1285})
return _cons({x_1287, tmp21})
else
_raise(_Match, "mlbasis.sml:1033:5")
end
end
map_1334 = function(a_1335)
return function(a_1336)
if a_1336.tag == "nil" then
return _nil
elseif a_1336.tag == "::" then
local x_1339 = a_1336.payload[1]
local xs_1338 = a_1336.payload[2]
local tmp22 = a_1335(x_1339)
local tmp23 = map_1334(a_1335)
local tmp24 = tmp23(xs_1338)
return _cons({tmp22, tmp24})
else
_raise(_Match, "mlbasis.sml:1059:5")
end
end
end
foldl_1378 = function(a_1379)
return function(a_1380)
return function(a_1381)
if a_1381.tag == "nil" then
return a_1380
elseif a_1381.tag == "::" then
local x_1385 = a_1381.payload[1]
local xs_1384 = a_1381.payload[2]
local tmp25 = foldl_1378(a_1379)
local tmp26 = a_1379({x_1385, a_1380})
local tmp27 = tmp25(tmp26)
return tmp27(xs_1384)
else
_raise(_Match, "mlbasis.sml:1084:5")
end
end
end
end
exists_1401 = function(a_1402)
return function(a_1403)
if a_1403.tag == "nil" then
return false
elseif a_1403.tag == "::" then
local x_1406 = a_1403.payload[1]
local xs_1405 = a_1403.payload[2]
local tmp28 = a_1402(x_1406)
if tmp28 then
return true
else
local tmp29 = exists_1401(a_1402)
return tmp29(xs_1405)
end
else
_raise(_Match, "mlbasis.sml:1089:5")
end
end
end
end
local tmp30 = (function(a_8306)
local x_8308 = a_8306[1]
local y_8309 = a_8306[2]
local a_8310 = x_8308 == y_8309
return not a_8310
end)({wordSize_1007, 64})
if tmp30 then
local tmp31 = _Fail("Word64 is not available")
_raise(tmp31, "word64.sml:32:14")
end
do
local ZERO_2339 = { tag = "ZERO" }
local function POSITIVE_2338(x)
return { tag = "POSITIVE", payload = x }
end
local function NEGATIVE_2337(x)
return { tag = "NEGATIVE", payload = x }
end
local wordSize__2_2373
do
local a_8549
do
local a_8554
do
local x_8557 = wordSize_1007
a_8554 = x_8557
end
local x_8559 = a_8554
local tmp_11453 = x_8559
local tmp_11452 = 0x2
a_8549 = {tmp_11453, tmp_11452}
end
local x_8551 = a_8549[1]
local y_8552 = a_8549[2]
wordSize__2_2373 = __Word_div(x_8551, y_8552)
end
do
local a_8560
do
local tmp_11454 = 0x1
local a_8568
do
local a_8569
do
local x_8572 = tmp_11454
local tmp_11456 = x_8572
local x_8575 = wordSize__2_2373
local tmp_11455 = x_8575
a_8569 = {tmp_11456, tmp_11455}
end
local x_8577 = a_8569[1]
local y_8578 = a_8569[2]
a_8568 = x_8577 << y_8578
end
local x_8580 = a_8568
local tmp_11458 = x_8580
local tmp_11457 = 0x1
a_8560 = {tmp_11458, tmp_11457}
end
local x_8562 = a_8560[1]
local y_8563 = a_8560[2]
end
POSITIVE_2338({ n = 1, 0x3B9ACA00 })
end
local initialPos_2925, next_2926
do
local next_2911 = function(a_2912)
local content_2916 = a_2912[1]
local file_2915 = a_2912[2]["file"]
local line_2914 = a_2912[2]["line"]
local exp_3987 = Substring_1832["getc"](content_2916)
if exp_3987.tag == "NONE" then
return NONE_386
elseif exp_3987.tag == "SOME" then
local c_2918 = exp_3987.payload[1]
local content_2917 = exp_3987.payload[2]
local newpos_2919
if c_2918 == "\n" then
local tmp_11637 = 1
local x_10423 = a_2912[2]["line"]
local tmp32 = __Int_add(x_10423, tmp_11637)
newpos_2919 = {["file"] = file_2915, ["line"] = tmp32, ["column"] = 1}
else
local tmp_11638 = 1
local x_10427 = a_2912[2]["column"]
local tmp33 = __Int_add(x_10427, tmp_11638)
newpos_2919 = {["file"] = file_2915, ["line"] = line_2914, ["column"] = tmp33}
end
return SOME_385({c_2918, newpos_2919, {content_2917, newpos_2919}})
else
_raise(_Match, "string-stream.sml:6:46")
end
end
do
next_2926 = next_2911
initialPos_2925 = function(a_10429)
return {["file"] = a_10429, ["line"] = 1, ["column"] = 1}
end
end
end
local ParserCombinator_2964 = function(S_2965)
local tmp_3282
do
local Stream_2966 = S_2965["_Stream"]
local function Message_2969(x)
return { tag = "Message", payload = x }
end
local function Expected_2968(x)
return { tag = "Expected", payload = x }
end
local function Unexpected_2967(x)
return { tag = "Unexpected", payload = x }
end
local mergeError_2970 = function(a_2971)
local e1_2973 = a_2971[1]
local e2_2972 = a_2971[2]
local exp_3991 = S_2965["comparePos"]({e1_2973["pos"], e2_2972["pos"]})
if exp_3991.tag == "EQUAL" then
local tmp34 = _AT_1282({e1_2973["messages"], e2_2972["messages"]})
return {["pos"] = e1_2973["pos"], ["messages"] = tmp34}
elseif exp_3991.tag == "LESS" then
return e2_2972
elseif exp_3991.tag == "GREATER" then
return e1_2973
else
_raise(_Match, "parser-combinator.fun:18:53")
end
end
local showError_2974 = function(a_2975)
local pos_2977 = a_2975["pos"]
local messages_2976 = a_2975["messages"]
local tmp_11643, tmp_11644
do
local tmp_11639, tmp_11640
do
tmp_11640 = S_2965["showPos"](pos_2977)
tmp_11639 = ": "
end
tmp_11644 = tmp_11640 .. tmp_11639
local a_10444 = ", "
local tmp35 = map_1334(function(a_2981)
if a_2981.tag == "Message" then
local s_2978 = a_2981.payload
return s_2978
elseif a_2981.tag == "Expected" then
local s_2979 = a_2981.payload
local tmp_11641 = "expected "
return tmp_11641 .. s_2979
elseif a_2981.tag == "Unexpected" then
local s_2980 = a_2981.payload
local tmp_11642 = "unexpected "
return tmp_11642 .. s_2980
else
_raise(_Match, "parser-combinator.fun:22:107")
end
end)
local tmp36 = tmp35(messages_2976)
tmp_11643 = (function(a_10445)
local a_10450 = _VectorOrArray_fromList(a_10445)
local x_10452 = a_10450
local x_10455 = a_10444
local result_10449 = table_pack(concat_688(x_10452, x_10455))
local a_10456 = sub_547({result_10449, 0})
local x_10458 = a_10456
return x_10458
end)(tmp36)
end
return tmp_11644 .. tmp_11643
end
local function Ok_PRIME_2983(x)
return { tag = "Ok'", payload = x }
end
local function Err_2982(x)
return { tag = "Err", payload = x }
end
local function ParseError_2985(x)
return { tag = "ParseError", payload = x }
end
local function Ok_2984(x)
return { tag = "Ok", payload = x }
end
local runParser_2986 = function(a_2987)
return function(a_2988)
return function(a_2989)
return function(a_2990)
local tmp37 = Stream_2966["initialPos"](a_2989)
local exp_3995 = a_2987({["stream"] = a_2990, ["pos"] = tmp37, ["user"] = a_2988})
if exp_3995.tag == "Ok'" then
local result_2999 = exp_3995.payload[1]
local user_2995 = exp_3995.payload[3]["user"]
return Ok_2984({result_2999, user_2995})
elseif exp_3995.tag == "Err" then
local e_3000 = exp_3995.payload[2]
local tmp38 = showError_2974(e_3000)
return ParseError_2985(tmp38)
else
_raise(_Match, "parser-combinator.fun:31:38")
end
end
end
end
end
local _LT_DOLLAR_GT_3012 = function(a_3013)
local f_3015 = a_3013[1]
local p_3014 = a_3013[2]
return function(s_3016)
local exp_4000 = p_3014(s_3016)
if exp_4000.tag == "Ok'" then
local result_3019 = exp_4000.payload[1]
local consumed_3018 = exp_4000.payload[2]
local s_3017 = exp_4000.payload[3]
local tmp39 = f_3015(result_3019)
return Ok_PRIME_2983({tmp39, consumed_3018, s_3017})
elseif exp_4000.tag == "Err" then
local e_3020 = exp_4000.payload
return Err_2982(e_3020)
else
_raise(_Match, "parser-combinator.fun:50:23")
end
end
end
local _LT_DOLLAR_3021 = function(a_3022)
local x_3024 = a_3022[1]
local p_3023 = a_3022[2]
return function(s_3025)
local exp_4002 = p_3023(s_3025)
if exp_4002.tag == "Ok'" then
local consumed_3027 = exp_4002.payload[2]
local s_3026 = exp_4002.payload[3]
return Ok_PRIME_2983({x_3024, consumed_3027, s_3026})
elseif exp_4002.tag == "Err" then
local e_3028 = exp_4002.payload
return Err_2982(e_3028)
else
_raise(_Match, "parser-combinator.fun:53:22")
end
end
end
local _LT_ASTER_GT_3033 = function(a_3034)
local f_3036 = a_3034[1]
local p_3035 = a_3034[2]
return function(s_3037)
local exp_4005 = f_3036(s_3037)
if exp_4005.tag == "Ok'" then
local f_PRIME_3040 = exp_4005.payload[1]
local consumed_3039 = exp_4005.payload[2]
local s_3038 = exp_4005.payload[3]
local exp_4006 = p_3035(s_3038)
if exp_4006.tag == "Ok'" then
local x_3043 = exp_4006.payload[1]
local consumed_PRIME_3042 = exp_4006.payload[2]
local s_3041 = exp_4006.payload[3]
local tmp40 = f_PRIME_3040(x_3043)
local tmp41
if consumed_3039 then
tmp41 = true
else
tmp41 = consumed_PRIME_3042
end
return Ok_PRIME_2983({tmp40, tmp41, s_3041})
elseif exp_4006.tag == "Err" then
local consumed_PRIME_3045 = exp_4006.payload[1]
local e_3044 = exp_4006.payload[2]
local tmp42
if consumed_3039 then
tmp42 = true
else
tmp42 = consumed_PRIME_3045
end
return Err_2982({tmp42, e_3044})
else
_raise(_Match, "parser-combinator.fun:58:53")
end
elseif exp_4005.tag == "Err" then
local e_3046 = exp_4005.payload
return Err_2982(e_3046)
else
_raise(_Match, "parser-combinator.fun:57:23")
end
end
end
local _LT_ASTER_3047 = function(a_3048)
local p_3050 = a_3048[1]
local q_3049 = a_3048[2]
return function(s_3051)
local exp_4008 = p_3050(s_3051)
if exp_4008.tag == "Ok'" then
local x_3054 = exp_4008.payload[1]
local consumed_3053 = exp_4008.payload[2]
local s_3052 = exp_4008.payload[3]
local exp_4009 = q_3049(s_3052)
if exp_4009.tag == "Ok'" then
local consumed_PRIME_3056 = exp_4009.payload[2]
local s_3055 = exp_4009.payload[3]
local tmp43
if consumed_3053 then
tmp43 = true
else
tmp43 = consumed_PRIME_3056
end
return Ok_PRIME_2983({x_3054, tmp43, s_3055})
elseif exp_4009.tag == "Err" then
local consumed_PRIME_3058 = exp_4009.payload[1]
local e_3057 = exp_4009.payload[2]
local tmp44
if consumed_3053 then
tmp44 = true
else
tmp44 = consumed_PRIME_3058
end
return Err_2982({tmp44, e_3057})
else
_raise(_Match, "parser-combinator.fun:64:51")
end
elseif exp_4008.tag == "Err" then
local e_3059 = exp_4008.payload
return Err_2982(e_3059)
else
_raise(_Match, "parser-combinator.fun:63:22")
end
end
end
local _GT_GT_3060 = function(a_3061)
local p_3063 = a_3061[1]
local q_3062 = a_3061[2]
return function(s_3064)
local exp_4011 = p_3063(s_3064)
if exp_4011.tag == "Ok'" then
local consumed_3066 = exp_4011.payload[2]
local s_3065 = exp_4011.payload[3]
local exp_4012 = q_3062(s_3065)
if exp_4012.tag == "Ok'" then
local y_3069 = exp_4012.payload[1]
local consumed_PRIME_3068 = exp_4012.payload[2]
local s_3067 = exp_4012.payload[3]
local tmp45
if consumed_3066 then
tmp45 = true
else
tmp45 = consumed_PRIME_3068
end
return Ok_PRIME_2983({y_3069, tmp45, s_3067})
elseif exp_4012.tag == "Err" then
local consumed_PRIME_3071 = exp_4012.payload[1]
local e_3070 = exp_4012.payload[2]
local tmp46
if consumed_3066 then
tmp46 = true
else
tmp46 = consumed_PRIME_3071
end
return Err_2982({tmp46, e_3070})
else
_raise(_Match, "parser-combinator.fun:71:51")
end
elseif exp_4011.tag == "Err" then
local e_3072 = exp_4011.payload
return Err_2982(e_3072)
else
_raise(_Match, "parser-combinator.fun:70:22")
end
end
end
local _GT_GT_EQ_3073 = function(a_3074)
local p_3076 = a_3074[1]
local f_3075 = a_3074[2]
return function(s_3077)
local exp_4014 = p_3076(s_3077)
if exp_4014.tag == "Ok'" then
local x_3080 = exp_4014.payload[1]
local consumed_3079 = exp_4014.payload[2]
local s_3078 = exp_4014.payload[3]
local tmp47 = f_3075(x_3080)
local exp_4015 = tmp47(s_3078)
if exp_4015.tag == "Ok'" then
local y_3083 = exp_4015.payload[1]
local consumed_PRIME_3082 = exp_4015.payload[2]
local s_3081 = exp_4015.payload[3]
local tmp48
if consumed_3079 then
tmp48 = true
else
tmp48 = consumed_PRIME_3082
end
return Ok_PRIME_2983({y_3083, tmp48, s_3081})
elseif exp_4015.tag == "Err" then
local consumed_PRIME_3085 = exp_4015.payload[1]
local e_3084 = exp_4015.payload[2]
local tmp49
if consumed_3079 then
tmp49 = true
else
tmp49 = consumed_PRIME_3085
end
return Err_2982({tmp49, e_3084})
else
_raise(_Match, "parser-combinator.fun:77:52")
end
elseif exp_4014.tag == "Err" then
local e_3086 = exp_4014.payload
return Err_2982(e_3086)
else
_raise(_Match, "parser-combinator.fun:76:23")
end
end
end
local _LT_BAR_GT_3087 = function(a_3088)
local p_3090 = a_3088[1]
local q_3089 = a_3088[2]
return function(s_3091)
local exp_4017 = p_3090(s_3091)
if exp_4017.tag == "Ok'" then
local r_3092 = exp_4017.payload
return Ok_PRIME_2983(r_3092)
else
local tmp50
if exp_4017.tag == "Err" then
tmp50 = not exp_4017.payload[1]
else
tmp50 = false
end
if tmp50 then
local e1_3093 = exp_4017.payload[2]
local exp_4018 = q_3089(s_3091)
if exp_4018.tag == "Ok'" then
local r_3094 = exp_4018.payload
return Ok_PRIME_2983(r_3094)
else
local tmp51
if exp_4018.tag == "Err" then
tmp51 = exp_4018.payload[1]
else
tmp51 = false
end
if tmp51 then
local e2_3095 = exp_4018.payload[2]
return Err_2982({true, e2_3095})
else
local tmp52
if exp_4018.tag == "Err" then
tmp52 = not exp_4018.payload[1]
else
tmp52 = false
end
if tmp52 then
local e2_3096 = exp_4018.payload[2]
local tmp53 = mergeError_2970({e1_3093, e2_3096})
return Err_2982({false, tmp53})
else
_raise(_Match, "parser-combinator.fun:85:47")
end
end
end
else
local tmp54
if exp_4017.tag == "Err" then
tmp54 = exp_4017.payload[1]
else
tmp54 = false
end
if tmp54 then
local e_3097 = exp_4017.payload[2]
return Err_2982({true, e_3097})
else
_raise(_Match, "parser-combinator.fun:83:23")
end
end
end
end
end
local _LT_QUESTION_GT_3102 = function(a_3103)
local p_3105 = a_3103[1]
local msg_3104 = a_3103[2]
return function(s_3106)
local exp_4021 = p_3105(s_3106)
if exp_4021.tag == "Ok'" then
local r_3107 = exp_4021.payload
return Ok_PRIME_2983(r_3107)
else
local tmp55
if exp_4021.tag == "Err" then
tmp55 = not exp_4021.payload[1]
else
tmp55 = false
end
if tmp55 then
local tmp56 = Expected_2968(msg_3104)
return Err_2982({false, {["pos"] = s_3106["pos"], ["messages"] = _list{ n = 1, tmp56 }}})
elseif exp_4021.tag == "Err" then
local e_3108 = exp_4021.payload
return Err_2982(e_3108)
else
_raise(_Match, "parser-combinator.fun:93:25")
end
end
end
end
local try_3111 = function(a_3112)
return function(s_3114)
local exp_4023 = a_3112(s_3114)
if exp_4023.tag == "Ok'" then
local r_3115 = exp_4023.payload
return Ok_PRIME_2983(r_3115)
elseif exp_4023.tag == "Err" then
local e_3116 = exp_4023.payload[2]
return Err_2982({false, e_3116})
else
_raise(_Match, "parser-combinator.fun:98:21")
end
end
end
local getState_3117 = function(s_3118)
return Ok_PRIME_2983({s_3118["user"], false, s_3118})
end
local setState_3120 = function(a_3121)
return function(s_3123)
return Ok_PRIME_2983({nil, false, {["stream"] = s_3123["stream"], ["pos"] = s_3123["pos"], ["user"] = a_3121}})
end
end
local modifyState_3124 = function(a_3125)
return function(s_3127)
local tmp57 = a_3125(s_3127["user"])
return Ok_PRIME_2983({nil, false, {["stream"] = s_3127["stream"], ["pos"] = s_3127["pos"], ["user"] = tmp57}})
end
end
local token_3128 = function(a_3129)
return function(s_3131)
local exp_4027 = S_2965["_Stream"]["next"](s_3131["stream"])
if exp_4027.tag == "NONE" then
local tmp58 = Unexpected_2967("end of input")
return Err_2982({false, {["pos"] = s_3131["pos"], ["messages"] = _list{ n = 1, tmp58 }}})
elseif exp_4027.tag == "SOME" then
local tok_3134 = exp_4027.payload[1]
local pos_3133 = exp_4027.payload[2]
local stream_3132 = exp_4027.payload[3]
local exp_4028 = a_3129(tok_3134)
if exp_4028.tag == "NONE" then
local tmp59 = S_2965["showToken"](tok_3134)
local tmp60 = Unexpected_2967(tmp59)
return Err_2982({false, {["pos"] = pos_3133, ["messages"] = _list{ n = 1, tmp60 }}})
elseif exp_4028.tag == "SOME" then
local value_3135 = exp_4028.payload
return Ok_PRIME_2983({value_3135, true, {["stream"] = stream_3132, ["pos"] = pos_3133, ["user"] = s_3131["user"]}})
else
_raise(_Match, "parser-combinator.fun:106:80")
end
else
_raise(_Match, "parser-combinator.fun:104:48")
end
end
end
local choice_3136
choice_3136 = function(a_3137)
if a_3137.tag == "nil" then
local a_10471 = ""
return function(s_10474)
local tmp61 = Message_2969(a_10471)
return Err_2982({false, {["pos"] = s_10474["pos"], ["messages"] = _list{ n = 1, tmp61 }}})
end
elseif a_3137.tag == "::" then
local p_3139 = a_3137.payload[1]
local ps_3138 = a_3137.payload[2]
local tmp62 = choice_3136(ps_3138)
return _LT_BAR_GT_3087({p_3139, tmp62})
else
_raise(_Match, "parser-combinator.fun:110:5")
end
end
local many_3140
many_3140 = function(a_3141)
return function(s_3143)
local exp_4031 = a_3141(s_3143)
local tmp63
if exp_4031.tag == "Ok'" then
tmp63 = exp_4031.payload[2]
else
tmp63 = false
end
if tmp63 then
local x_3145 = exp_4031.payload[1]
local s_3144 = exp_4031.payload[3]
local tmp64 = many_3140(a_3141)
local exp_4032 = tmp64(s_3144)
if exp_4032.tag == "Ok'" then
local xs_3147 = exp_4032.payload[1]
local s_3146 = exp_4032.payload[3]
local tmp65 = _cons({x_3145, xs_3147})
return Ok_PRIME_2983({tmp65, true, s_3146})
elseif exp_4032.tag == "Err" then
local e_3148 = exp_4032.payload[2]
return Err_2982({true, e_3148})
else
_raise(_Match, "parser-combinator.fun:113:47")
end
else
local tmp66
if exp_4031.tag == "Ok'" then
tmp66 = not exp_4031.payload[2]
else
tmp66 = false
end
if tmp66 then
local s_3149 = exp_4031.payload[3]
local tmp67 = Message_2969("many: combinator 'many' is applied to a parser that accepts an empty string")
return Err_2982({false, {["pos"] = s_3149["pos"], ["messages"] = _list{ n = 1, tmp67 }}})
else
local tmp68
if exp_4031.tag == "Err" then
tmp68 = not exp_4031.payload[1]
else
tmp68 = false
end
if tmp68 then
return Ok_PRIME_2983({_nil, false, s_3143})
else
local tmp69
if exp_4031.tag == "Err" then
tmp69 = exp_4031.payload[1]
else
tmp69 = false
end
if tmp69 then
local e_3151 = exp_4031.payload[2]
return Err_2982({true, e_3151})
else
_raise(_Match, "parser-combinator.fun:112:22")
end
end
end
end
end
end
local skipMany_3157 = function(a_3158)
local p_10500
p_10500 = function(a_10501)
local tmp70 = _GT_GT_3060({a_3158, p_10500})
local a_10513 = nil
local tmp71 = _LT_BAR_GT_3087({tmp70, function(s_10516)
return Ok_PRIME_2983({a_10513, false, s_10516})
end})
return tmp71(a_10501)
end
return p_10500
end
local sepBy_3170 = function(a_3171)
local p_10547 = a_3171[1]
local sep_10548 = a_3171[2]
local tmp74 = _GT_GT_EQ_3073({p_10547, function(x_10549)
local tmp72 = _GT_GT_3060({sep_10548, p_10547})
local tmp73 = many_3140(tmp72)
return _GT_GT_EQ_3073({tmp73, function(xs_10550)
local a_10551 = _cons({x_10549, xs_10550})
return function(s_10554)
return Ok_PRIME_2983({a_10551, false, s_10554})
end
end})
end})
local a_10559 = _nil
return _LT_BAR_GT_3087({tmp74, function(s_10562)
return Ok_PRIME_2983({a_10559, false, s_10562})
end})
end
local anyToken_3174 = token_3128(SOME_385)
local optional_3175 = function(a_3176)
return function(s_3178)
local exp_4039 = a_3176(s_3178)
if exp_4039.tag == "Ok'" then
local x_3181 = exp_4039.payload[1]
local consumed_3180 = exp_4039.payload[2]
local s_3179 = exp_4039.payload[3]
local tmp75 = SOME_385(x_3181)
return Ok_PRIME_2983({tmp75, consumed_3180, s_3179})
else
local tmp76
if exp_4039.tag == "Err" then
tmp76 = not exp_4039.payload[1]
else
tmp76 = false
end
if tmp76 then
return Ok_PRIME_2983({NONE_386, false, s_3178})
else
local tmp77
if exp_4039.tag == "Err" then
tmp77 = exp_4039.payload[1]
else
tmp77 = false
end
if tmp77 then
local e_3182 = exp_4039.payload[2]
return Err_2982({true, e_3182})
else
_raise(_Match, "parser-combinator.fun:127:26")
end
end
end
end
end
local optional___3183 = function(a_3184)
return function(s_3186)
local exp_4041 = a_3184(s_3186)
if exp_4041.tag == "Ok'" then
local consumed_3188 = exp_4041.payload[2]
local s_3187 = exp_4041.payload[3]
return Ok_PRIME_2983({nil, consumed_3188, s_3187})
else
local tmp78
if exp_4041.tag == "Err" then
tmp78 = not exp_4041.payload[1]
else
tmp78 = false
end
if tmp78 then
return Ok_PRIME_2983({nil, false, s_3186})
else
local tmp79
if exp_4041.tag == "Err" then
tmp79 = exp_4041.payload[1]
else
tmp79 = false
end
if tmp79 then
local e_3189 = exp_4041.payload[2]
return Err_2982({true, e_3189})
else
_raise(_Match, "parser-combinator.fun:131:27")
end
end
end
end
end
local notFollowedBy_3190 = function(a_3191)
return function(s_3193)
local exp_4043 = a_3191(s_3193)
if exp_4043.tag == "Ok'" then
local tmp80 = Unexpected_2967("token")
return Err_2982({false, {["pos"] = s_3193["pos"], ["messages"] = _list{ n = 1, tmp80 }}})
elseif exp_4043.tag == "Err" then
return Ok_PRIME_2983({nil, false, s_3193})
else
_raise(_Match, "parser-combinator.fun:135:31")
end
end
end
local tmp81 = notFollowedBy_3190(anyToken_3174)
local eof_3195 = _LT_QUESTION_GT_3102({tmp81, "end of input"})
local currentPos_3202 = function(s_3203)
return Ok_PRIME_2983({s_3203["pos"], false, s_3203})
end
local withPos_3205 = function(a_3206)
return function(s_3208)
local pos0_3209 = s_3208["pos"]
local exp_4046 = a_3206(s_3208)
if exp_4046.tag == "Ok'" then
local x_3212 = exp_4046.payload[1]
local consumed_3211 = exp_4046.payload[2]
local s_3210 = exp_4046.payload[3]
return Ok_PRIME_2983({{x_3212, pos0_3209, s_3210["pos"]}, consumed_3211, s_3210})
elseif exp_4046.tag == "Err" then
local e_3213 = exp_4046.payload
return Err_2982(e_3213)
else
_raise(_Match, "parser-combinator.fun:142:42")
end
end
end
local try_3268 = try_3111
local skipMany1_3266 = function(a_10563)
local tmp82 = skipMany_3157(a_10563)
return _GT_GT_3060({a_10563, tmp82})
end
local sepBy1_3264 = function(a_10576)
local p_10578 = a_10576[1]
local sep_10579 = a_10576[2]
return _GT_GT_EQ_3073({p_10578, function(x_10580)
local tmp83 = _GT_GT_3060({sep_10579, p_10578})
local tmp84 = many_3140(tmp83)
return _GT_GT_EQ_3073({tmp84, function(xs_10581)
local a_10582 = _cons({x_10580, xs_10581})
return function(s_10585)
return Ok_PRIME_2983({a_10582, false, s_10585})
end
end})
end})
end
local sepBy_3263 = sepBy_3170
local runParser_3262 = runParser_2986
local pure_3261 = function(a_10586)
return function(s_10589)
return Ok_PRIME_2983({a_10586, false, s_10589})
end
end
local many1_3257 = function(a_10590)
return _GT_GT_EQ_3073({a_10590, function(x_10593)
local tmp85 = many_3140(a_10590)
return _GT_GT_EQ_3073({tmp85, function(xs_10594)
local a_10595 = _cons({x_10593, xs_10594})
return function(s_10598)
return Ok_PRIME_2983({a_10595, false, s_10598})
end
end})
end})
end
local fix_3254 = function(a_10606)
local p_10609
p_10609 = function(a_10610)
local tmp86 = a_10606(p_10609)
return tmp86(a_10610)
end
return p_10609
end
local fail_3253 = function(a_10613)
return function(s_10616)
local tmp87 = Message_2969(a_10613)
return Err_2982({false, {["pos"] = s_10616["pos"], ["messages"] = _list{ n = 1, tmp87 }}})
end
end
local delay_3252 = function(a_10621)
return function(s_10624)
local tmp88 = a_10621(nil)
return tmp88(s_10624)
end
end
local between_3250 = function(a_10643)
return function(a_10644)
local open___10646 = a_10643[1]
local close_10647 = a_10643[2]
local tmp89 = _GT_GT_3060({open___10646, a_10644})
return _LT_ASTER_3047({tmp89, close_10647})
end
end
local _GT_GT_EQ_3247 = _GT_GT_EQ_3073
local _GT_GT_3246 = _GT_GT_3060
local _LT_BAR_GT_3245 = _LT_BAR_GT_3087
local _LT_ASTER_GT_3243 = _LT_ASTER_GT_3033
local _LT_ASTER_3242 = _LT_ASTER_3047
local _LT_DOLLAR_GT_3241 = _LT_DOLLAR_GT_3012
local _LT_DOLLAR_3240 = _LT_DOLLAR_3021
local Stream_3271 = {["initialPos"] = Stream_2966["initialPos"], ["next"] = Stream_2966["next"]}
local Operators_3270
do
local _GT_GT_EQ_3239 = _GT_GT_EQ_3073
local _GT_GT_3238 = _GT_GT_3060
local _LT_BAR_GT_3237 = _LT_BAR_GT_3087
local _LT_ASTER_GT_3235 = _LT_ASTER_GT_3033
local _LT_ASTER_3234 = _LT_ASTER_3047
local _LT_DOLLAR_GT_3233 = _LT_DOLLAR_GT_3012
local _LT_DOLLAR_3232 = _LT_DOLLAR_3021
Operators_3270 = {["<$"] = _LT_DOLLAR_3232, ["<$>"] = _LT_DOLLAR_GT_3233, ["<*"] = _LT_ASTER_3234, ["<*>"] = _LT_ASTER_GT_3235, ["<?>"] = _LT_QUESTION_GT_3102, ["<|>"] = _LT_BAR_GT_3237, [">>"] = _GT_GT_3238, [">>="] = _GT_GT_EQ_3239}
end
local tmp_3281 = {["<$"] = _LT_DOLLAR_3240, ["<$>"] = _LT_DOLLAR_GT_3241, ["<*"] = _LT_ASTER_3242, ["<*>"] = _LT_ASTER_GT_3243, ["<?>"] = _LT_QUESTION_GT_3102, ["<|>"] = _LT_BAR_GT_3245, [">>"] = _GT_GT_3246, [">>="] = _GT_GT_EQ_3247, ["Ok"] = Ok_2984, ["ParseError"] = ParseError_2985, ["anyToken"] = anyToken_3174, ["between"] = between_3250, ["choice"] = choice_3136, ["currentPos"] = currentPos_3202, ["delay"] = delay_3252, ["eof"] = eof_3195, ["fail"] = fail_3253, ["fix"] = fix_3254, ["getState"] = getState_3117, ["label"] = _LT_QUESTION_GT_3102, ["many"] = many_3140, ["many1"] = many1_3257, ["modifyState"] = modifyState_3124, ["notFollowedBy"] = notFollowedBy_3190, ["optional"] = optional_3175, ["optional_"] = optional___3183, ["pure"] = pure_3261, ["runParser"] = runParser_3262, ["sepBy"] = sepBy_3263, ["sepBy1"] = sepBy1_3264, ["setState"] = setState_3120, ["skipMany"] = skipMany_3157, ["skipMany1"] = skipMany1_3266, ["token"] = token_3128, ["try"] = try_3268, ["withPos"] = withPos_3205, ["_Operators"] = Operators_3270, ["_Stream"] = Stream_3271}
tmp_3282 = tmp_3281
end
return tmp_3282
end
local CharParser_3290 = function(P_3291)
local char_3292 = function(a_3293)
return P_3291["token"](function(c_PRIME_3295)
if a_3293 == c_PRIME_3295 then
return SOME_385(a_3293)
else
return NONE_386
end
end)
end
local oneOf_3296 = function(a_3297)
local tmp90 = map_1334(char_3292)
local tmp91 = tmp90(a_3297)
return P_3291["choice"](tmp91)
end
local noneOf_3299 = function(a_3300)
return P_3291["token"](function(c_3302)
local tmp92 = exists_1401(function(c_PRIME_3303)
return c_3302 == c_PRIME_3303
end)
local tmp93 = tmp92(a_3300)
if tmp93 then
return NONE_386
else
return SOME_385(c_3302)
end
end)
end
local satisfy_3304 = function(a_3305)
return P_3291["token"](function(c_3307)
local tmp94 = a_3305(c_3307)
if tmp94 then
return SOME_385(c_3307)
else
return NONE_386
end
end)
end
local tmp96 = P_3291["token"](function(c_10652)
local tmp95 = isSpace_1249(c_10652)
if tmp95 then
return SOME_385(c_10652)
else
return NONE_386
end
end)
local space_3308 = P_3291["_Operators"]["<?>"]({tmp96, "space"})
local tmp97 = P_3291["many"](space_3308)
local tmp98 = P_3291["_Operators"]["<?>"]({tmp97, "white space"})
local spaces_3309 = P_3291["_Operators"][">>="]({tmp98, function(a_3310)
return P_3291["pure"](nil)
end})
local a_10653 = "\n"
local tmp99 = P_3291["token"](function(c_PRIME_10656)
if a_10653 == c_PRIME_10656 then
return SOME_385(a_10653)
else
return NONE_386
end
end)
local newline_3311 = P_3291["_Operators"]["<?>"]({tmp99, "lf new-line"})
local a_10657 = "\r"
local tmp100 = P_3291["token"](function(c_PRIME_10660)
if a_10657 == c_PRIME_10660 then
return SOME_385(a_10657)
else
return NONE_386
end
end)
local a_10661 = "\n"
local tmp101 = P_3291["token"](function(c_PRIME_10664)
if a_10661 == c_PRIME_10664 then
return SOME_385(a_10661)
else
return NONE_386
end
end)
local tmp102 = P_3291["_Operators"][">>"]({tmp100, tmp101})
local crlf_3312 = P_3291["_Operators"]["<?>"]({tmp102, "crlf new-line"})
local tmp103 = P_3291["_Operators"]["<|>"]({newline_3311, crlf_3312})
local endOfLine_3313 = P_3291["_Operators"]["<?>"]({tmp103, "new-line"})
local a_10665 = "\t"
local tmp104 = P_3291["token"](function(c_PRIME_10668)
if a_10665 == c_PRIME_10668 then
return SOME_385(a_10665)
else
return NONE_386
end
end)
local tab_3314 = P_3291["_Operators"]["<?>"]({tmp104, "tab"})
local tmp106 = P_3291["token"](function(c_10672)
local tmp105 = isUpper_1251(c_10672)
if tmp105 then
return SOME_385(c_10672)
else
return NONE_386
end
end)
local upper_3315 = P_3291["_Operators"]["<?>"]({tmp106, "uppercase letter"})
local tmp108 = P_3291["token"](function(c_10676)
local tmp107 = isLower_1247(c_10676)
if tmp107 then
return SOME_385(c_10676)
else
return NONE_386
end
end)
local lower_3316 = P_3291["_Operators"]["<?>"]({tmp108, "lowercase letter"})
local tmp110 = P_3291["token"](function(c_10680)
local tmp109 = isAlphaNum_1242(c_10680)
if tmp109 then
return SOME_385(c_10680)
else
return NONE_386
end
end)
local alphaNum_3317 = P_3291["_Operators"]["<?>"]({tmp110, "letter or digit"})
local tmp112 = P_3291["token"](function(c_10684)
local tmp111 = isAlpha_1241(c_10684)
if tmp111 then
return SOME_385(c_10684)
else
return NONE_386
end
end)
local letter_3318 = P_3291["_Operators"]["<?>"]({tmp112, "letter"})
local tmp114 = P_3291["token"](function(c_10688)
local tmp113 = isDigit_1244(c_10688)
if tmp113 then
return SOME_385(c_10688)
else
return NONE_386
end
end)
local digit_3319 = P_3291["_Operators"]["<?>"]({tmp114, "digit"})
local tmp116 = P_3291["token"](function(c_10692)
local tmp115 = isHexDigit_1246(c_10692)
if tmp115 then
return SOME_385(c_10692)
else
return NONE_386
end
end)
local hexDigit_3320 = P_3291["_Operators"]["<?>"]({tmp116, "hexadecimal digit"})
local tmp118 = P_3291["token"](function(c_10696)
local tmp_11647 = "0"
local tmp117
if tmp_11647 <= c_10696 then
local tmp_11648 = "7"
tmp117 = c_10696 <= tmp_11648
else
tmp117 = false
end
if tmp117 then
return SOME_385(c_10696)
else
return NONE_386
end
end)
local octDigit_3321 = P_3291["_Operators"]["<?>"]({tmp118, "octal digit"})
local digitToInt_3323 = function(a_3324)
local tmp_11649 = "0"
local tmp119
if tmp_11649 <= a_3324 then
local tmp_11650 = "9"
tmp119 = a_3324 <= tmp_11650
else
tmp119 = false
end
if tmp119 then
local tmp_11651, tmp_11652
do
tmp_11652 = ord_1210(a_3324)
tmp_11651 = ord_1210("0")
end
return __Int_sub(tmp_11652, tmp_11651)
else
local tmp_11653 = "A"
local tmp120
if tmp_11653 <= a_3324 then
local tmp_11654 = "F"
tmp120 = a_3324 <= tmp_11654
else
tmp120 = false
end
if tmp120 then
local tmp_11657, tmp_11658
do
local tmp_11655, tmp_11656
do
tmp_11656 = ord_1210(a_3324)
tmp_11655 = ord_1210("A")
end
tmp_11658 = __Int_sub(tmp_11656, tmp_11655)
tmp_11657 = 10
end
return __Int_add(tmp_11658, tmp_11657)
else
local tmp_11661, tmp_11662
do
local tmp_11659, tmp_11660
do
tmp_11660 = ord_1210(a_3324)
tmp_11659 = ord_1210("a")
end
tmp_11662 = __Int_sub(tmp_11660, tmp_11659)
tmp_11661 = 10
end
return __Int_add(tmp_11662, tmp_11661)
end
end
end
local digitValue_3326 = P_3291["_Operators"]["<$>"]({digitToInt_3323, digit_3319})
local hexDigitValue_3327 = P_3291["_Operators"]["<$>"]({digitToInt_3323, hexDigit_3320})
local octDigitValue_3328 = P_3291["_Operators"]["<$>"]({digitToInt_3323, octDigit_3321})
local anyChar_3329 = P_3291["anyToken"]
local string_3331 = function(a_3332)
local n_3334 = #a_3332
local go_3335
go_3335 = function(a_3336)
if a_3336 >= n_3334 then
return P_3291["pure"](a_3332)
else
local a_10757 = sub_1118({a_3332, a_3336})
local tmp121 = P_3291["token"](function(c_PRIME_10760)
if a_10757 == c_PRIME_10760 then
return SOME_385(a_10757)
else
return NONE_386
end
end)
local tmp_11663 = 1
local tmp122 = __Int_add(a_3336, tmp_11663)
local tmp123 = go_3335(tmp122)
return P_3291["_Operators"][">>"]({tmp121, tmp123})
end
end
return go_3335(0)
end
local tmp_3339 = {["alphaNum"] = alphaNum_3317, ["anyChar"] = anyChar_3329, ["char"] = char_3292, ["crlf"] = crlf_3312, ["digit"] = digit_3319, ["digitValue"] = digitValue_3326, ["endOfLine"] = endOfLine_3313, ["hexDigit"] = hexDigit_3320, ["hexDigitValue"] = hexDigitValue_3327, ["letter"] = letter_3318, ["lower"] = lower_3316, ["newline"] = newline_3311, ["noneOf"] = noneOf_3299, ["octDigit"] = octDigit_3321, ["octDigitValue"] = octDigitValue_3328, ["oneOf"] = oneOf_3296, ["satisfy"] = satisfy_3304, ["space"] = space_3308, ["spaces"] = spaces_3309, ["string"] = string_3331, ["tab"] = tab_3314, ["upper"] = upper_3315}
return tmp_3339
end
local ADD_3360, CONST_3363, COS_3355, DIV_3357, MUL_3358, SIN_3356, SUB_3359, VAR_3362, diff_3420, simplify_3364, toTeXString_3442
do
function CONST_3363(x)
return { tag = "CONST", payload = x }
end
function VAR_3362(x)
return { tag = "VAR", payload = x }
end
local function NEG_3361(x)
return { tag = "NEG", payload = x }
end
function ADD_3360(x)
return { tag = "ADD", payload = x }
end
function SUB_3359(x)
return { tag = "SUB", payload = x }
end
function MUL_3358(x)
return { tag = "MUL", payload = x }
end
function DIV_3357(x)
return { tag = "DIV", payload = x }
end
function SIN_3356(x)
return { tag = "SIN", payload = x }
end
function COS_3355(x)
return { tag = "COS", payload = x }
end
local simplifyInside_3365
simplifyInside_3365 = function(a_3406)
if a_3406.tag == "CONST" then
return a_3406
elseif a_3406.tag == "VAR" then
return a_3406
elseif a_3406.tag == "NEG" then
local x_3409 = a_3406.payload
local tmp153 = simplify_3364(x_3409)
return NEG_3361(tmp153)
elseif a_3406.tag == "ADD" then
local x_3411 = a_3406.payload[1]
local y_3410 = a_3406.payload[2]
local tmp154 = simplify_3364(x_3411)
local tmp155 = simplify_3364(y_3410)
return ADD_3360({tmp154, tmp155})
elseif a_3406.tag == "SUB" then
local x_3413 = a_3406.payload[1]
local y_3412 = a_3406.payload[2]
local tmp156 = simplify_3364(x_3413)
local tmp157 = simplify_3364(y_3412)
return SUB_3359({tmp156, tmp157})
elseif a_3406.tag == "MUL" then
local x_3415 = a_3406.payload[1]
local y_3414 = a_3406.payload[2]
local tmp158 = simplify_3364(x_3415)
local tmp159 = simplify_3364(y_3414)
return MUL_3358({tmp158, tmp159})
elseif a_3406.tag == "DIV" then
local x_3417 = a_3406.payload[1]
local y_3416 = a_3406.payload[2]
local tmp160 = simplify_3364(x_3417)
local tmp161 = simplify_3364(y_3416)
return DIV_3357({tmp160, tmp161})
elseif a_3406.tag == "SIN" then
local x_3418 = a_3406.payload
local tmp162 = simplify_3364(x_3418)
return SIN_3356(tmp162)
elseif a_3406.tag == "COS" then
local x_3419 = a_3406.payload
local tmp163 = simplify_3364(x_3419)
return COS_3355(tmp163)
else
_raise(_Match, "expr.sml:43:5")
end
end
simplify_3364 = function(a_3366)
local exp_4056 = simplifyInside_3365(a_3366)
if exp_4056.tag == "CONST" then
return exp_4056
elseif exp_4056.tag == "VAR" then
return exp_4056
else
local tmp124
if exp_4056.tag == "NEG" then
tmp124 = exp_4056.payload.tag == "CONST"
else
tmp124 = false
end
if tmp124 then
local x_3370 = exp_4056.payload.payload
local tmp125 = _Int_negate(x_3370)
return CONST_3363(tmp125)
else
local tmp126
if exp_4056.tag == "NEG" then
tmp126 = exp_4056.payload.tag == "NEG"
else
tmp126 = false
end
if tmp126 then
local x_3371 = exp_4056.payload.payload
return x_3371
elseif exp_4056.tag == "NEG" then
return exp_4056
else
local tmp127
if exp_4056.tag == "ADD" then
if exp_4056.payload[1].tag == "CONST" then
tmp127 = exp_4056.payload[1].payload == 0
else
tmp127 = false
end
else
tmp127 = false
end
if tmp127 then
local y_3373 = exp_4056.payload[2]
return y_3373
else
local tmp128
if exp_4056.tag == "ADD" then
if exp_4056.payload[2].tag == "CONST" then
tmp128 = exp_4056.payload[2].payload == 0
else
tmp128 = false
end
else
tmp128 = false
end
if tmp128 then
local x_3374 = exp_4056.payload[1]
return x_3374
else
local tmp129
if exp_4056.tag == "ADD" then
if exp_4056.payload[1].tag == "CONST" then
tmp129 = exp_4056.payload[2].tag == "CONST"
else
tmp129 = false
end
else
tmp129 = false
end
if tmp129 then
local x_3376 = exp_4056.payload[1].payload
local y_3375 = exp_4056.payload[2].payload
local tmp130 = __Int_add(x_3376, y_3375)
return CONST_3363(tmp130)
elseif exp_4056.tag == "ADD" then
return exp_4056
else
local tmp131
if exp_4056.tag == "SUB" then
if exp_4056.payload[1].tag == "CONST" then
tmp131 = exp_4056.payload[1].payload == 0
else
tmp131 = false
end
else
tmp131 = false
end
if tmp131 then
local y_3378 = exp_4056.payload[2]
return NEG_3361(y_3378)
else
local tmp132
if exp_4056.tag == "SUB" then
if exp_4056.payload[2].tag == "CONST" then
tmp132 = exp_4056.payload[2].payload == 0
else
tmp132 = false
end
else
tmp132 = false
end
if tmp132 then
local x_3379 = exp_4056.payload[1]
return x_3379
else
local tmp133
if exp_4056.tag == "SUB" then
if exp_4056.payload[1].tag == "CONST" then
tmp133 = exp_4056.payload[2].tag == "CONST"
else
tmp133 = false
end
else
tmp133 = false
end
if tmp133 then
local x_3381 = exp_4056.payload[1].payload
local y_3380 = exp_4056.payload[2].payload
local tmp134 = __Int_sub(x_3381, y_3380)
return CONST_3363(tmp134)
elseif exp_4056.tag == "SUB" then
return exp_4056
else
local tmp135
if exp_4056.tag == "MUL" then
if exp_4056.payload[1].tag == "CONST" then
tmp135 = exp_4056.payload[1].payload == 0
else
tmp135 = false
end
else
tmp135 = false
end
if tmp135 then
local z_3383 = exp_4056.payload[1]
return z_3383
else
local tmp136
if exp_4056.tag == "MUL" then
if exp_4056.payload[2].tag == "CONST" then
tmp136 = exp_4056.payload[2].payload == 0
else
tmp136 = false
end
else
tmp136 = false
end
if tmp136 then
local z_3384 = exp_4056.payload[2]
return z_3384
else
local tmp137
if exp_4056.tag == "MUL" then
if exp_4056.payload[1].tag == "CONST" then
tmp137 = exp_4056.payload[1].payload == 1
else
tmp137 = false
end
else
tmp137 = false
end
if tmp137 then
local y_3385 = exp_4056.payload[2]
return y_3385
else
local tmp138
if exp_4056.tag == "MUL" then
if exp_4056.payload[2].tag == "CONST" then
tmp138 = exp_4056.payload[2].payload == 1
else
tmp138 = false
end
else
tmp138 = false
end
if tmp138 then
local x_3386 = exp_4056.payload[1]
return x_3386
else
local tmp139
if exp_4056.tag == "MUL" then
if exp_4056.payload[1].tag == "NEG" then
tmp139 = exp_4056.payload[2].tag == "NEG"
else
tmp139 = false
end
else
tmp139 = false
end
if tmp139 then
local x_3388 = exp_4056.payload[1].payload
local y_3387 = exp_4056.payload[2].payload
return MUL_3358({x_3388, y_3387})
else
local tmp140
if exp_4056.tag == "MUL" then
tmp140 = exp_4056.payload[1].tag == "NEG"
else
tmp140 = false
end
if tmp140 then
local x_3390 = exp_4056.payload[1].payload
local y_3389 = exp_4056.payload[2]
local tmp141 = MUL_3358({x_3390, y_3389})
return NEG_3361(tmp141)
else
local tmp142
if exp_4056.tag == "MUL" then
tmp142 = exp_4056.payload[2].tag == "NEG"
else
tmp142 = false
end
if tmp142 then
local x_3392 = exp_4056.payload[1]
local y_3391 = exp_4056.payload[2].payload
local tmp143 = MUL_3358({x_3392, y_3391})
return NEG_3361(tmp143)
elseif exp_4056.tag == "MUL" then
return exp_4056
else
local tmp144
if exp_4056.tag == "DIV" then
if exp_4056.payload[1].tag == "CONST" then
tmp144 = exp_4056.payload[1].payload == 0
else
tmp144 = false
end
else
tmp144 = false
end
if tmp144 then
local z_3394 = exp_4056.payload[1]
return z_3394
else
local tmp145
if exp_4056.tag == "DIV" then
if exp_4056.payload[2].tag == "CONST" then
tmp145 = exp_4056.payload[2].payload == 1
else
tmp145 = false
end
else
tmp145 = false
end
if tmp145 then
local x_3395 = exp_4056.payload[1]
return x_3395
else
local tmp146
if exp_4056.tag == "DIV" then
if exp_4056.payload[1].tag == "NEG" then
tmp146 = exp_4056.payload[2].tag == "NEG"
else
tmp146 = false
end
else
tmp146 = false
end
if tmp146 then
local x_3397 = exp_4056.payload[1].payload
local y_3396 = exp_4056.payload[2].payload
return DIV_3357({x_3397, y_3396})
else
local tmp147
if exp_4056.tag == "DIV" then
tmp147 = exp_4056.payload[1].tag == "NEG"
else
tmp147 = false
end
if tmp147 then
local x_3399 = exp_4056.payload[1].payload
local y_3398 = exp_4056.payload[2]
local tmp148 = DIV_3357({x_3399, y_3398})
return NEG_3361(tmp148)
else
local tmp149
if exp_4056.tag == "DIV" then
tmp149 = exp_4056.payload[2].tag == "NEG"
else
tmp149 = false
end
if tmp149 then
local x_3401 = exp_4056.payload[1]
local y_3400 = exp_4056.payload[2].payload
local tmp150 = DIV_3357({x_3401, y_3400})
return NEG_3361(tmp150)
elseif exp_4056.tag == "DIV" then
return exp_4056
else
local tmp151
if exp_4056.tag == "SIN" then
if exp_4056.payload.tag == "CONST" then
tmp151 = exp_4056.payload.payload == 0
else
tmp151 = false
end
else
tmp151 = false
end
if tmp151 then
local z_3403 = exp_4056.payload
return z_3403
elseif exp_4056.tag == "SIN" then
return exp_4056
else
local tmp152
if exp_4056.tag == "COS" then
if exp_4056.payload.tag == "CONST" then
tmp152 = exp_4056.payload.payload == 0
else
tmp152 = false
end
else
tmp152 = false
end
if tmp152 then
return CONST_3363(1)
elseif exp_4056.tag == "COS" then
return exp_4056
else
_raise(_Match, "expr.sml:11:20")
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
diff_3420 = function(a_3421)
local d_3423
d_3423 = function(a_3424)
if a_3424.tag == "CONST" then
return CONST_3363(0)
elseif a_3424.tag == "VAR" then
local v_PRIME_3425 = a_3424.payload
if a_3421 == v_PRIME_3425 then
return CONST_3363(1)
else
return CONST_3363(0)
end
elseif a_3424.tag == "NEG" then
local x_3426 = a_3424.payload
local tmp164 = d_3423(x_3426)
return NEG_3361(tmp164)
elseif a_3424.tag == "ADD" then
local x_3428 = a_3424.payload[1]
local y_3427 = a_3424.payload[2]
local tmp165 = d_3423(x_3428)
local tmp166 = d_3423(y_3427)
return ADD_3360({tmp165, tmp166})
elseif a_3424.tag == "SUB" then
local x_3430 = a_3424.payload[1]
local y_3429 = a_3424.payload[2]
local tmp167 = d_3423(x_3430)
local tmp168 = d_3423(y_3429)
return SUB_3359({tmp167, tmp168})
elseif a_3424.tag == "MUL" then
local x_3432 = a_3424.payload[1]
local y_3431 = a_3424.payload[2]
local tmp169 = d_3423(x_3432)
local tmp170 = MUL_3358({tmp169, y_3431})
local tmp171 = d_3423(y_3431)
local tmp172 = MUL_3358({x_3432, tmp171})
return ADD_3360({tmp170, tmp172})
elseif a_3424.tag == "DIV" then
local x_3434 = a_3424.payload[1]
local y_3433 = a_3424.payload[2]
local tmp173 = d_3423(x_3434)
local tmp174 = MUL_3358({tmp173, y_3433})
local tmp175 = d_3423(y_3433)
local tmp176 = MUL_3358({x_3434, tmp175})
local tmp177 = SUB_3359({tmp174, tmp176})
local tmp178 = MUL_3358({y_3433, y_3433})
return DIV_3357({tmp177, tmp178})
elseif a_3424.tag == "SIN" then
local x_3435 = a_3424.payload
local tmp179 = COS_3355(x_3435)
local tmp180 = d_3423(x_3435)
return MUL_3358({tmp179, tmp180})
elseif a_3424.tag == "COS" then
local x_3436 = a_3424.payload
local tmp181 = SIN_3356(x_3436)
local tmp182 = d_3423(x_3436)
local tmp183 = MUL_3358({tmp181, tmp182})
return NEG_3361(tmp183)
else
_raise(_Match, "expr.sml:52:22")
end
end
return d_3423
end
local paren_3437 = function(a_3438)
return function(a_3439)
if a_3438 then
local tmp_11665, tmp_11666
do
local tmp_11664 = "\\left("
tmp_11666 = tmp_11664 .. a_3439
tmp_11665 = "\\right)"
end
return tmp_11666 .. tmp_11665
elseif not a_3438 then
return a_3439
else
_raise(_Match, "expr.sml:66:5")
end
end
end
toTeXString_3442 = function(a_3443)
return function(a_3444)
if a_3444.tag == "CONST" then
local x_3447 = a_3444.payload
local tmp_11667 = 0
if x_3447 >= tmp_11667 then
return toString_992(x_3447)
else
local tmp_11668 = 0
local tmp184 = paren_3437(a_3443 > tmp_11668)
local tmp_11669, tmp_11670
do
tmp_11670 = "-"
local tmp185 = _Int_negate(x_3447)
tmp_11669 = toString_992(tmp185)
end
return tmp184(tmp_11670 .. tmp_11669)
end
elseif a_3444.tag == "VAR" then
local x_3448 = a_3444.payload
return x_3448
elseif a_3444.tag == "NEG" then
local x_3449 = a_3444.payload
local tmp_11671 = 0
local tmp186 = paren_3437(a_3443 > tmp_11671)
local tmp_11672, tmp_11673
do
tmp_11673 = "-"
local tmp187 = toTeXString_3442(1)
tmp_11672 = tmp187(x_3449)
end
return tmp186(tmp_11673 .. tmp_11672)
elseif a_3444.tag == "ADD" then
local x_3451 = a_3444.payload[1]
local y_3450 = a_3444.payload[2]
local tmp_11674 = 0
local tmp188 = paren_3437(a_3443 > tmp_11674)
local tmp_11677, tmp_11678
do
local tmp_11675, tmp_11676
do
local tmp189 = toTeXString_3442(0)
tmp_11676 = tmp189(x_3451)
tmp_11675 = "+"
end
tmp_11678 = tmp_11676 .. tmp_11675
local tmp190 = toTeXString_3442(1)
tmp_11677 = tmp190(y_3450)
end
return tmp188(tmp_11678 .. tmp_11677)
elseif a_3444.tag == "SUB" then
local x_3453 = a_3444.payload[1]
local y_3452 = a_3444.payload[2]
local tmp_11679 = 0
local tmp191 = paren_3437(a_3443 > tmp_11679)
local tmp_11682, tmp_11683
do
local tmp_11680, tmp_11681
do
local tmp192 = toTeXString_3442(0)
tmp_11681 = tmp192(x_3453)
tmp_11680 = "-"
end
tmp_11683 = tmp_11681 .. tmp_11680
local tmp193 = toTeXString_3442(1)
tmp_11682 = tmp193(y_3452)
end
return tmp191(tmp_11683 .. tmp_11682)
elseif a_3444.tag == "MUL" then
local x_3455 = a_3444.payload[1]
local y_3454 = a_3444.payload[2]
local tmp_11684 = 1
local tmp194 = paren_3437(a_3443 > tmp_11684)
local tmp_11687, tmp_11688
do
local tmp_11685, tmp_11686
do
local tmp195 = toTeXString_3442(1)
tmp_11686 = tmp195(x_3455)
tmp_11685 = "\\cdot "
end
tmp_11688 = tmp_11686 .. tmp_11685
local tmp196 = toTeXString_3442(2)
tmp_11687 = tmp196(y_3454)
end
return tmp194(tmp_11688 .. tmp_11687)
elseif a_3444.tag == "DIV" then
local x_3457 = a_3444.payload[1]
local y_3456 = a_3444.payload[2]
local tmp_11689 = 1
local tmp197 = paren_3437(a_3443 > tmp_11689)
local tmp_11692, tmp_11693
do
local tmp_11690, tmp_11691
do
local tmp198 = toTeXString_3442(1)
tmp_11691 = tmp198(x_3457)
tmp_11690 = "/"
end
tmp_11693 = tmp_11691 .. tmp_11690
local tmp199 = toTeXString_3442(2)
tmp_11692 = tmp199(y_3456)
end
return tmp197(tmp_11693 .. tmp_11692)
elseif a_3444.tag == "SIN" then
local x_3458 = a_3444.payload
local tmp_11694 = 1
local tmp200 = paren_3437(a_3443 > tmp_11694)
local tmp_11697, tmp_11698
do
local tmp_11695, tmp_11696
do
tmp_11696 = "\\sin{"
local tmp201 = toTeXString_3442(2)
tmp_11695 = tmp201(x_3458)
end
tmp_11698 = tmp_11696 .. tmp_11695
tmp_11697 = "}"
end
return tmp200(tmp_11698 .. tmp_11697)
elseif a_3444.tag == "COS" then
local x_3459 = a_3444.payload
local tmp_11699 = 1
local tmp202 = paren_3437(a_3443 > tmp_11699)
local tmp_11702, tmp_11703
do
local tmp_11700, tmp_11701
do
tmp_11701 = "\\cos{"
local tmp203 = toTeXString_3442(2)
tmp_11700 = tmp203(x_3459)
end
tmp_11703 = tmp_11701 .. tmp_11700
tmp_11702 = "}"
end
return tmp202(tmp_11703 .. tmp_11702)
else
_raise(_Match, "expr.sml:68:28")
end
end
end
end
local parse_3547
do
local P_3582
do
local showToken_3462 = function(a_3463)
return toString_1260(a_3463)
end
local showPos_3465 = function(a_3466)
local line_3468 = a_3466["line"]
local column_3467 = a_3466["column"]
local tmp_11709, tmp_11710
do
local tmp_11707, tmp_11708
do
local tmp_11705, tmp_11706
do
local tmp_11704 = ":"
local x_10887 = a_3466["file"]
tmp_11706 = x_10887 .. tmp_11704
tmp_11705 = toString_992(line_3468)
end
tmp_11708 = tmp_11706 .. tmp_11705
tmp_11707 = ":"
end
tmp_11710 = tmp_11708 .. tmp_11707
tmp_11709 = toString_992(column_3467)
end
return tmp_11710 .. tmp_11709
end
local comparePos_3470 = function(a_3471)
local exp_4066
do
local s_10891 = a_3471[1]["file"]
local t_10892 = a_3471[2]["file"]
if s_10891 == t_10892 then
exp_4066 = EQUAL_892
else
local x_10895 = a_3471[1]["file"]
local y_10896 = a_3471[2]["file"]
if x_10895 < y_10896 then
exp_4066 = LESS_893
else
exp_4066 = GREATER_891
end
end
end
if exp_4066.tag == "LESS" then
return LESS_893
elseif exp_4066.tag == "GREATER" then
return GREATER_891
elseif exp_4066.tag == "EQUAL" then
local exp_4067
do
local x_10899 = a_3471[1]["line"]
local y_10900 = a_3471[2]["line"]
if x_10899 == y_10900 then
exp_4067 = EQUAL_892
else
local x_10903 = a_3471[1]["line"]
local y_10904 = a_3471[2]["line"]
if x_10903 < y_10904 then
exp_4067 = LESS_893
else
exp_4067 = GREATER_891
end
end
end
if exp_4067.tag == "LESS" then
return LESS_893
elseif exp_4067.tag == "GREATER" then
return GREATER_891
elseif exp_4067.tag == "EQUAL" then
local x_10907 = a_3471[1]["column"]
local y_10908 = a_3471[2]["column"]
if x_10907 == y_10908 then
return EQUAL_892
else
local x_10911 = a_3471[1]["column"]
local y_10912 = a_3471[2]["column"]
if x_10911 < y_10912 then
return LESS_893
else
return GREATER_891
end
end
else
_raise(_Match, "expr.sml:90:52")
end
else
_raise(_Match, "expr.sml:87:39")
end
end
do
local Stream_3475 = {["initialPos"] = initialPos_2925, ["next"] = next_2926}
local P_3581 = ParserCombinator_2964({["comparePos"] = comparePos_3470, ["showPos"] = showPos_3465, ["showToken"] = showToken_3462, ["_Stream"] = Stream_3475})
P_3582 = P_3581
end
end
local CP_3518
do
local withPos_3515 = P_3582["withPos"]
local try_3514 = P_3582["try"]
local token_3513 = P_3582["token"]
local skipMany1_3512 = P_3582["skipMany1"]
local skipMany_3511 = P_3582["skipMany"]
local sepBy1_3510 = P_3582["sepBy1"]
local sepBy_3509 = P_3582["sepBy"]
local runParser_3508 = P_3582["runParser"]
local pure_3507 = P_3582["pure"]
local optional___3506 = P_3582["optional_"]
local optional_3505 = P_3582["optional"]
local notFollowedBy_3504 = P_3582["notFollowedBy"]
local many1_3503 = P_3582["many1"]
local many_3502 = P_3582["many"]
local label_3501 = P_3582["label"]
local fix_3500 = P_3582["fix"]
local fail_3499 = P_3582["fail"]
local delay_3498 = P_3582["delay"]
local choice_3497 = P_3582["choice"]
local between_3496 = P_3582["between"]
local ParseError_3495 = P_3582["ParseError"]
local Ok_3494 = P_3582["Ok"]
local _GT_GT_EQ_3493 = P_3582[">>="]
local _GT_GT_3492 = P_3582[">>"]
local _LT_BAR_GT_3491 = P_3582["<|>"]
local _LT_QUESTION_GT_3490 = P_3582["<?>"]
local _LT_ASTER_GT_3489 = P_3582["<*>"]
local _LT_ASTER_3488 = P_3582["<*"]
local _LT_DOLLAR_GT_3487 = P_3582["<$>"]
local _LT_DOLLAR_3486 = P_3582["<$"]
local Stream_3517 = {["initialPos"] = P_3582["_Stream"]["initialPos"], ["next"] = P_3582["_Stream"]["next"]}
local Operators_3516
do
local _GT_GT_EQ_3485 = P_3582["_Operators"][">>="]
local _GT_GT_3484 = P_3582["_Operators"][">>"]
local _LT_BAR_GT_3483 = P_3582["_Operators"]["<|>"]
local _LT_QUESTION_GT_3482 = P_3582["_Operators"]["<?>"]
local _LT_ASTER_GT_3481 = P_3582["_Operators"]["<*>"]
local _LT_ASTER_3480 = P_3582["_Operators"]["<*"]
local _LT_DOLLAR_GT_3479 = P_3582["_Operators"]["<$>"]
local _LT_DOLLAR_3478 = P_3582["_Operators"]["<$"]
Operators_3516 = {["<$"] = _LT_DOLLAR_3478, ["<$>"] = _LT_DOLLAR_GT_3479, ["<*"] = _LT_ASTER_3480, ["<*>"] = _LT_ASTER_GT_3481, ["<?>"] = _LT_QUESTION_GT_3482, ["<|>"] = _LT_BAR_GT_3483, [">>"] = _GT_GT_3484, [">>="] = _GT_GT_EQ_3485}
end
CP_3518 = CharParser_3290({["<$"] = _LT_DOLLAR_3486, ["<$>"] = _LT_DOLLAR_GT_3487, ["<*"] = _LT_ASTER_3488, ["<*>"] = _LT_ASTER_GT_3489, ["<?>"] = _LT_QUESTION_GT_3490, ["<|>"] = _LT_BAR_GT_3491, [">>"] = _GT_GT_3492, [">>="] = _GT_GT_EQ_3493, ["Ok"] = Ok_3494, ["ParseError"] = ParseError_3495, ["anyToken"] = P_3582["anyToken"], ["between"] = between_3496, ["choice"] = choice_3497, ["currentPos"] = P_3582["currentPos"], ["delay"] = delay_3498, ["eof"] = P_3582["eof"], ["fail"] = fail_3499, ["fix"] = fix_3500, ["getState"] = P_3582["getState"], ["label"] = label_3501, ["many"] = many_3502, ["many1"] = many1_3503, ["modifyState"] = P_3582["modifyState"], ["notFollowedBy"] = notFollowedBy_3504, ["optional"] = optional_3505, ["optional_"] = optional___3506, ["pure"] = pure_3507, ["runParser"] = runParser_3508, ["sepBy"] = sepBy_3509, ["sepBy1"] = sepBy1_3510, ["setState"] = P_3582["setState"], ["skipMany"] = skipMany_3511, ["skipMany1"] = skipMany1_3512, ["token"] = token_3513, ["try"] = try_3514, ["withPos"] = withPos_3515, ["_Operators"] = Operators_3516, ["_Stream"] = Stream_3517})
end
local tmp204 = P_3582["_Operators"]["<$"]({nil, CP_3518["space"]})
local tmp205 = P_3582["_Operators"]["<?>"]({tmp204, ""})
local whiteSpace_3519 = P_3582["skipMany"](tmp205)
local int_3523
do
local tmp206 = foldl_1378(function(a_3526)
local x_3525 = a_3526[1]
local tmp_11720, tmp_11721
do
local tmp_11718, tmp_11719
do
local tmp_11717 = 10
local y_10930 = a_3526[2]
tmp_11719 = __Int_mul(tmp_11717, y_10930)
tmp_11718 = ord_1210(x_3525)
end
tmp_11721 = __Int_add(tmp_11719, tmp_11718)
tmp_11720 = ord_1210("0")
end
return __Int_sub(tmp_11721, tmp_11720)
end)
local tmp207 = tmp206(0)
local tmp208 = P_3582["many1"](CP_3518["digit"])
local a_10916 = P_3582["_Operators"]["<$>"]({tmp207, tmp208})
int_3523 = P_3582["_Operators"]["<*"]({a_10916, whiteSpace_3519})
end
local identifier_3527
do
local tmp209 = P_3582["many1"](CP_3518["letter"])
local tmp210 = P_3582["_Operators"]["<$>"]({function(a_1149)
local a_5666 = _VectorOrArray_fromList(a_1149)
local x_5668 = a_5666
local result_1151 = table_pack(concat_688(x_5668))
local a_5672 = sub_547({result_1151, 0})
local x_5674 = a_5672
return x_5674
end, tmp209})
local tmp212 = P_3582["_Operators"][">>="]({tmp210, function(name_3528)
local tmp211
if name_3528 == "sin" then
tmp211 = true
else
tmp211 = name_3528 == "cos"
end
if tmp211 then
return P_3582["fail"]("reserved name")
else
return P_3582["pure"](name_3528)
end
end})
local tmp213 = P_3582["try"](tmp212)
local a_10934 = P_3582["_Operators"]["<?>"]({tmp213, "identifier"})
identifier_3527 = P_3582["_Operators"]["<*"]({a_10934, whiteSpace_3519})
end
local lparen_3529
do
local a_10940 = CP_3518["char"]("(")
lparen_3529 = P_3582["_Operators"]["<*"]({a_10940, whiteSpace_3519})
end
local rparen_3530
do
local a_10946 = CP_3518["char"](")")
rparen_3530 = P_3582["_Operators"]["<*"]({a_10946, whiteSpace_3519})
end
local expr_3531 = P_3582["fix"](function(expr_3532)
local tmp214 = P_3582["_Operators"]["<$>"]({CONST_3363, int_3523})
local tmp215 = P_3582["_Operators"]["<$>"]({VAR_3362, identifier_3527})
local tmp216 = P_3582["between"]({lparen_3529, rparen_3530})
local tmp217 = tmp216(expr_3532)
local tmp218 = CP_3518["string"]("sin")
local tmp219 = P_3582["notFollowedBy"](CP_3518["letter"])
local tmp220 = P_3582["_Operators"][">>"]({tmp218, tmp219})
local a_10952 = P_3582["try"](tmp220)
local tmp221 = P_3582["_Operators"]["<*"]({a_10952, whiteSpace_3519})
local tmp222 = P_3582["between"]({lparen_3529, rparen_3530})
local tmp223 = P_3582["_Operators"]["<$>"]({SIN_3356, expr_3532})
local tmp224 = tmp222(tmp223)
local tmp225 = P_3582["_Operators"][">>"]({tmp221, tmp224})
local tmp226 = CP_3518["string"]("cos")
local tmp227 = P_3582["notFollowedBy"](CP_3518["letter"])
local tmp228 = P_3582["_Operators"][">>"]({tmp226, tmp227})
local a_10958 = P_3582["try"](tmp228)
local tmp229 = P_3582["_Operators"]["<*"]({a_10958, whiteSpace_3519})
local tmp230 = P_3582["between"]({lparen_3529, rparen_3530})
local tmp231 = P_3582["_Operators"]["<$>"]({COS_3355, expr_3532})
local tmp232 = tmp230(tmp231)
local tmp233 = P_3582["_Operators"][">>"]({tmp229, tmp232})
local tmp234 = P_3582["_Operators"]["<|>"]({tmp225, tmp233})
local tmp235 = P_3582["_Operators"]["<|>"]({tmp217, tmp234})
local tmp236 = P_3582["_Operators"]["<|>"]({tmp215, tmp235})
local factor_3533 = P_3582["_Operators"]["<|>"]({tmp214, tmp236})
local term1_3534
term1_3534 = function(a_3535)
local a_10964 = CP_3518["char"]("*")
local tmp237 = P_3582["_Operators"]["<*"]({a_10964, whiteSpace_3519})
local tmp238 = P_3582["_Operators"][">>"]({tmp237, factor_3533})
local tmp240 = P_3582["_Operators"][">>="]({tmp238, function(y_3537)
local tmp239 = MUL_3358({a_3535, y_3537})
return term1_3534(tmp239)
end})
local a_10970 = CP_3518["char"]("/")
local tmp241 = P_3582["_Operators"]["<*"]({a_10970, whiteSpace_3519})
local tmp242 = P_3582["_Operators"][">>"]({tmp241, factor_3533})
local tmp244 = P_3582["_Operators"][">>="]({tmp242, function(y_3538)
local tmp243 = DIV_3357({a_3535, y_3538})
return term1_3534(tmp243)
end})
local tmp245 = P_3582["pure"](a_3535)
local tmp246 = P_3582["_Operators"]["<|>"]({tmp244, tmp245})
return P_3582["_Operators"]["<|>"]({tmp240, tmp246})
end
local term_3539 = P_3582["_Operators"][">>="]({factor_3533, term1_3534})
local expr1_3540
expr1_3540 = function(a_3541)
local a_10976 = CP_3518["char"]("+")
local tmp247 = P_3582["_Operators"]["<*"]({a_10976, whiteSpace_3519})
local tmp248 = P_3582["_Operators"][">>"]({tmp247, term_3539})
local tmp250 = P_3582["_Operators"][">>="]({tmp248, function(y_3543)
local tmp249 = ADD_3360({a_3541, y_3543})
return expr1_3540(tmp249)
end})
local a_10982 = CP_3518["char"]("-")
local tmp251 = P_3582["_Operators"]["<*"]({a_10982, whiteSpace_3519})
local tmp252 = P_3582["_Operators"][">>"]({tmp251, term_3539})
local tmp254 = P_3582["_Operators"][">>="]({tmp252, function(y_3544)
local tmp253 = SUB_3359({a_3541, y_3544})
return expr1_3540(tmp253)
end})
local tmp255 = P_3582["pure"](a_3541)
local tmp256 = P_3582["_Operators"]["<|>"]({tmp254, tmp255})
return P_3582["_Operators"]["<|>"]({tmp250, tmp256})
end
return P_3582["_Operators"][">>="]({term_3539, expr1_3540})
end)
local function Ok_3546(x)
return { tag = "Ok", payload = x }
end
local function Fail_3545(x)
return { tag = "Fail", payload = x }
end
parse_3547 = function(a_3548)
local tmp257 = P_3582["runParser"](expr_3531)
local tmp258 = tmp257(nil)
local tmp259 = tmp258("input")
local tmp_11722 = "input"
local tmp260 = Substring_1832["full"](a_3548)
local exp_4074 = tmp259({tmp260, {["file"] = tmp_11722, ["line"] = 1, ["column"] = 1}})
if exp_4074.tag == "Ok" then
local x_3550 = exp_4074.payload[1]
return Ok_3546(x_3550)
elseif exp_4074.tag == "ParseError" then
local msg_3551 = exp_4074.payload
return Fail_3545(msg_3551)
else
_raise(_Match, "expr.sml:126:30")
end
end
end
local toTeXString_3559 = toTeXString_3442(0)
return {diff = diff_3420, parse = parse_3547, simplify = simplify_3364, toTeXString = toTeXString_3559}
$(SML_LIB)/basis/basis.mlb
$(SML_LIB)/pluto/pluto.mlb
expr.sml
structure Expr = struct
datatype expr = CONST of Int.int
| VAR of string
| NEG of expr
| ADD of expr * expr
| SUB of expr * expr
| MUL of expr * expr
| DIV of expr * expr
| SIN of expr
| COS of expr
fun simplify exp = case simplifyInside exp of
exp as CONST _ => exp
| exp as VAR _ => exp
| NEG (CONST x) => CONST (~ x)
| NEG (NEG x) => x
| exp as NEG _ => exp
| ADD (CONST 0, y) => y
| ADD (x, CONST 0) => x
| ADD (CONST x, CONST y) => CONST (x + y)
| exp as ADD _ => exp
| SUB (CONST 0, y) => NEG y
| SUB (x, CONST 0) => x
| SUB (CONST x, CONST y) => CONST (x - y)
| exp as SUB _ => exp
| MUL (z as CONST 0, _) => z
| MUL (_, z as CONST 0) => z
| MUL (CONST 1, y) => y
| MUL (x, CONST 1) => x
| MUL (NEG x, NEG y) => MUL (x, y)
| MUL (NEG x, y) => NEG (MUL (x, y))
| MUL (x, NEG y) => NEG (MUL (x, y))
| exp as MUL _ => exp
| DIV (z as CONST 0, _) => z
| DIV (x, CONST 1) => x
| DIV (NEG x, NEG y) => DIV (x, y)
| DIV (NEG x, y) => NEG (DIV (x, y))
| DIV (x, NEG y) => NEG (DIV (x, y))
| exp as DIV _ => exp
| SIN (z as CONST 0) => z
| exp as SIN _ => exp
| COS (CONST 0) => CONST 1
| exp as COS _ => exp
and simplifyInside (exp as CONST _) = exp
| simplifyInside (exp as VAR _) = exp
| simplifyInside (NEG x) = NEG (simplify x)
| simplifyInside (ADD (x, y)) = ADD (simplify x, simplify y)
| simplifyInside (SUB (x, y)) = SUB (simplify x, simplify y)
| simplifyInside (MUL (x, y)) = MUL (simplify x, simplify y)
| simplifyInside (DIV (x, y)) = DIV (simplify x, simplify y)
| simplifyInside (SIN x) = SIN (simplify x)
| simplifyInside (COS x) = COS (simplify x)
fun diff v = let fun d (CONST _) = CONST 0
| d (VAR v') = if v = v' then
CONST 1
else
CONST 0
| d (NEG x) = NEG (d x)
| d (ADD (x, y)) = ADD (d x, d y)
| d (SUB (x, y)) = SUB (d x, d y)
| d (MUL (x, y)) = ADD (MUL (d x, y), MUL (x, d y))
| d (DIV (x, y)) = DIV (SUB (MUL (d x, y), MUL (x, d y)), MUL (y, y))
| d (SIN x) = MUL (COS x, d x)
| d (COS x) = NEG (MUL (SIN x, d x))
in d
end
fun paren true x = "\\left(" ^ x ^ "\\right)"
| paren false x = x
fun toTeXString prec exp = case exp of
CONST x => if x >= 0 then
Int.toString x
else
paren (prec > 0) ("-" ^ Int.toString (~ x))
| VAR x => x
| NEG x => paren (prec > 0) ("-" ^ toTeXString 1 x)
| ADD (x, y) => paren (prec > 0) (toTeXString 0 x ^ "+" ^ toTeXString 1 y)
| SUB (x, y) => paren (prec > 0) (toTeXString 0 x ^ "-" ^ toTeXString 1 y)
| MUL (x, y) => paren (prec > 1) (toTeXString 1 x ^ "\\cdot " ^ toTeXString 2 y)
| DIV (x, y) => paren (prec > 1) (toTeXString 1 x ^ "/" ^ toTeXString 2 y)
| SIN x => paren (prec > 1) ("\\sin{" ^ toTeXString 2 x ^ "}")
| COS x => paren (prec > 1) ("\\cos{" ^ toTeXString 2 x ^ "}")
end
structure ExprParser = struct
structure P = ParserCombinator (structure Stream = StringStream
fun showToken c = Char.toString c
fun showPos { file, line, column } = file ^ ":" ^ Int.toString line ^ ":" ^ Int.toString column
fun comparePos (p : Stream.pos, q : Stream.pos)
= case String.compare (#file p, #file q) of
LESS => LESS
| GREATER => GREATER
| EQUAL => case Int.compare (#line p, #line q) of
LESS => LESS
| GREATER => GREATER
| EQUAL => Int.compare (#column p, #column q)
type state = unit
)
structure CP = CharParser (P)
open P.Operators
infix 4 <$> <$ <*> <*
infix 1 >> >>=
infixr 1 <|>
infix 0 <?>
val whiteSpace = P.skipMany ((() <$ CP.space) <?> "")
fun lexeme p = p <* whiteSpace
val int : Int.int P.parser = lexeme (List.foldl (fn (x,y) => 10 * y + ord x - ord #"0") 0 <$> P.many1 CP.digit)
val identifier : string P.parser = lexeme (P.try ((String.implode <$> P.many1 CP.letter) >>= (fn name => if name = "sin" orelse name = "cos" then P.fail "reserved name" else P.pure name)) <?> "identifier")
val lparen = lexeme (CP.char #"(")
val rparen = lexeme (CP.char #")")
val expr = P.fix (fn expr =>
let val factor = Expr.CONST <$> int
<|> Expr.VAR <$> identifier
<|> P.between (lparen, rparen) expr
<|> (lexeme (P.try (CP.string "sin" >> P.notFollowedBy CP.letter)) >> P.between (lparen, rparen) (Expr.SIN <$> expr))
<|> (lexeme (P.try (CP.string "cos" >> P.notFollowedBy CP.letter)) >> P.between (lparen, rparen) (Expr.COS <$> expr))
fun term1 x = (lexeme (CP.char #"*") >> factor >>= (fn y => term1 (Expr.MUL (x, y))))
<|> (lexeme (CP.char #"/") >> factor >>= (fn y => term1 (Expr.DIV (x, y))))
<|> P.pure x
val term = factor >>= term1
fun expr1 x = (lexeme (CP.char #"+") >> term >>= (fn y => expr1 (Expr.ADD (x, y))))
<|> (lexeme (CP.char #"-") >> term >>= (fn y => expr1 (Expr.SUB (x, y))))
<|> P.pure x
in term >>= expr1
end
)
datatype 'a result = Ok of 'a
| Fail of string
fun parse (input : string) = case P.runParser expr () "input" (StringStream.fromString { file = "input", content = input }) of
P.Ok (x, _) => Ok x
| P.ParseError msg => Fail msg
end
structure export = struct
val parse = ExprParser.parse : string -> Expr.expr ExprParser.result
val simplify = Expr.simplify : Expr.expr -> Expr.expr
val diff = Expr.diff : string -> Expr.expr -> Expr.expr
val toTeXString = Expr.toTeXString 0 : Expr.expr -> string
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment