]> git.lizzy.rs Git - metalua.git/blob - src/samples/lex_switch_test.mlua
Merge remote branch 'origin/master'
[metalua.git] / src / samples / lex_switch_test.mlua
1 -- This is a simple and somewhat stupid example of how to switch
2 -- lexers dynamically. Behind a V, X and Y are the only reserved
3 -- keywords. In normal conditions, X and Y aren't keywords and can be
4 -- used as variables.
5
6 -{ block:
7    require 'lexer'
8    local my_lexer = lexer.lexer:clone() -- no keywords
9    my_lexer:add{"X", "Y"}
10    mlp.lexer:add "V"
11
12    function num(lx)
13       local a = lx:next()
14       assert(a.tag=='Number')
15       return a
16    end
17       
18    my_parser = gg.list{
19       gg.multisequence{
20          { "X", num, builder = |x| `Table{ x[1], +{0} } },
21          { "Y", num, builder = |y| `Table{ +{0}, y[1] } },
22          default = gg.sequence{ mlp.id, builder = |x| `Pair{ `String{x[1][1]},`True } } },
23       separators = { ',', ';' },
24       builder = function(l) l.tag='Table'; return l end }
25
26    mlp.expr:add{ "V", gg.with_lexer(my_lexer, my_parser), builder = unpack } }
27
28 -- Use the special lexer:
29 foo = V X 1, Y 2, X 3, 
30       for, foo, in, tag, function -- check that these aren't keywords in my_lexer
31
32 -- Use X and Y as Id, in the unpolluted lexer:
33 print "Vector:"
34 X = table.tostring(foo, 60)
35 print (X)
36
37 print "Sum:" -- Ready for a functional one-liner? :)
38 Y = |v| table.ifold (|a,b| table.imap (|c,d| c+d, a, b), {0,0}, v) 
39 table.print (Y(foo))
40