function display_parse_table(t) t:for_each(function(ts, es) if not t:is_nud() then io.write("_ ") end for i = 1, #ts do io.write("'" .. tostring(ts[i][1]) .. "'") local a = ts[i][2] local k = a:kind() if k == notation_action_kind.Skip then elseif k == notation_action_kind.Binder then io.write(" binder") elseif k == notation_action_kind.Binders then io.write(" binders") elseif k == notation_action_kind.Ext then io.write(" external") elseif k == notation_action_kind.ScopedExpr then io.write(" [_@" .. tostring(a:rbp()) .. ":" .. tostring(a:rec()) .. "]") elseif k == notation_action_kind.Expr then if a:rbp() == 0 then io.write(" _") else io.write(" _@" .. tostring(a:rbp())) end elseif k == notation_action_kind.Exprs then io.write(" [" .. tostring(a:rbp()) .. ", " .. tostring(a:rec()) .. ", " .. tostring(a:ini()) .. ", " .. tostring(a:is_fold_right()) .. "]") end io.write(" ") end print(":= ") while (not es:is_nil()) do print(" " .. tostring(es:head())) es = es:tail() end end) end function parse_table_size(t) local r = 0 t:for_each(function(ts, es) r = r + #es end) return r end local p = parse_table() assert(is_parse_table(p)) local ite = Const("ite") local ite2 = Const("ite2") local If = Const("if") p = p:add({"if", "then", "else"}, ite(Var(0), Var(1), Var(2))) p = p:add({"if", "then", "else"}, ite2(Var(0), Var(1), Var(2))) p = p:add({"if", "then"}, If(Var(0), Var(1))) display_parse_table(p) assert(parse_table_size(p) == 3) p = p:add({"if", "then", "else"}, ite2(Var(0), Var(1), Var(2)), false) print("======") display_parse_table(p) assert(parse_table_size(p) == 2) local f = Const("f") p = p:add({{"with", Skip}, "value"}, f(Var(0))) local Exists = Const("Exists") local ExistUnique = Const("ExistUnique") p = p:add({{"exists", Binders}, {",", scoped_expr_notation_action(Exists(Var(0)))}}, Var(0)) p = p:add({{"exist!", Binder}, {",", scoped_expr_notation_action(ExistUnique(Var(0)))}}, Var(0)) print("======") display_parse_table(p) check_error(function() p = p:add({{"with", Skip}, "value"}, f(Var(1))) end) check_error(function() p = p:add({{",", scoped_expr_notation_action(Exists(Var(0)))}}, Var(0)) end) local nat_add = Const({"nat", "add"}) local int_add = Const({"int", "add"}) check_error(function() p = p:add({{"+", 10}}, nat_add(Var(0), Var(1))) end) p = p:add({"if", "then", "else"}, ite(Var(0), Var(1), Var(2))) local a, p2 = p:find("if") assert(is_notation_action(a)) assert(a:kind() == notation_action_kind.Expr) assert(a:rbp() == 0) print("======") display_parse_table(p2) assert(parse_table_size(p2) == 3) local _, p2 = p2:find("then") local _, p2 = p2:find("else") print("======") assert(parse_table_size(p2) == 2) display_parse_table(p2) local es = p2:is_accepting() assert(es) assert(#es == 2) local p = parse_table(false) -- Create led table assert(not p:is_nud()) p = p:add({{"+", 10}}, nat_add(Var(0), Var(1))) p = p:add({{"+", 10}}, int_add(Var(0), Var(1))) print("======") display_parse_table(p) local nat_mul = Const({"nat", "mul"}) local int_mul = Const({"int", "mul"}) local p2 = parse_table(false) -- Create led table p2 = p2:add({{"*", 20}}, nat_mul(Var(0), Var(1))) p2 = p2:add({{"*", 20}}, int_mul(Var(0), Var(1))) print("======") display_parse_table(p2) p = p:merge(p2) print("======") display_parse_table(p) assert(parse_table_size(p) == 4) local p3 = parse_table() check_error(function() p:merge(p3) end) local a = scoped_expr_notation_action(Var(0), 10) assert(a:use_lambda_abstraction()) local a = scoped_expr_notation_action(Var(0), 10, false) assert(not a:use_lambda_abstraction()) local a = scoped_expr_notation_action(Var(0), 10, true) assert(a:use_lambda_abstraction()) assert(a:rbp() == 10)