]> git.lizzy.rs Git - metalua.git/blob - metalua/compiler/parser/annot/grammar.lua
Merge branch 'master' of ssh://git.eclipse.org/gitroot/koneki/org.eclipse.koneki...
[metalua.git] / metalua / compiler / parser / annot / grammar.lua
1 --------------------------------------------------------------------------------
2 -- Copyright (c) 2006-2013 Fabien Fleutot and others.
3 --
4 -- All rights reserved.
5 --
6 -- This program and the accompanying materials are made available
7 -- under the terms of the Eclipse Public License v1.0 which
8 -- accompanies this distribution, and is available at
9 -- http://www.eclipse.org/legal/epl-v10.html
10 --
11 -- This program and the accompanying materials are also made available
12 -- under the terms of the MIT public license which accompanies this
13 -- distribution, and is available at http://www.lua.org/license.html
14 --
15 -- Contributors:
16 --     Fabien Fleutot - API and implementation
17 --
18 --------------------------------------------------------------------------------
19
20 local gg    = require 'metalua.grammar.generator'
21
22 return function(M)
23     local _M = gg.future(M)
24     M.lexer :add '->'
25     local A = { }
26     local _A = gg.future(A)
27     M.annot = A
28
29     -- Type identifier: Lua keywords such as `"nil"` allowed.
30     function M.annot.tid(lx)
31         local w = lx :next()
32         local t = w.tag
33         if t=='Keyword' and w[1] :match '^[%a_][%w_]*$' or w.tag=='Id'
34         then return {tag='TId'; lineinfo=w.lineinfo; w[1]}
35         else return gg.parse_error (lx, 'tid expected') end
36     end
37
38     local field_types = { var='TVar'; const='TConst';
39                           currently='TCurrently'; field='TField' }
40
41     -- TODO check lineinfo
42     function M.annot.tf(lx)
43         local tk = lx:next()
44         local w = tk[1]
45         local tag = field_types[w]
46         if not tag then error ('Invalid field type '..w)
47         elseif tag=='TField' then return {tag='TField'} else
48             local te = M.te(lx)
49             return {tag=tag; te}
50         end
51     end
52
53     M.annot.tebar_content = gg.list{
54         name        = 'tebar content',
55         primary     = _A.te,
56         separators  = { ",", ";" },
57         terminators = ")" }
58
59     M.annot.tebar = gg.multisequence{
60         name = 'annot.tebar',
61         --{ '*', builder = 'TDynbar' }, -- maybe not user-available
62         { '(', _A.tebar_content, ')',
63           builder = function(x) return x[1] end },
64         { _A.te }
65     }
66
67     M.annot.te = gg.multisequence{
68         name = 'annot.te',
69         { _A.tid, builder=function(x) return x[1] end },
70         { '*', builder = 'TDyn' },
71         { "[",
72           gg.list{
73               primary = gg.sequence{
74                   _M.expr, "=", _A.tf,
75                   builder = 'TPair'
76               },
77               separators  = { ",", ";" },
78               terminators = { "]", "|" } },
79           gg.onkeyword{ "|", _A.tf },
80           "]",
81           builder = function(x)
82               local fields, other = unpack(x)
83               return { tag='TTable', other or {tag='TField'}, fields }
84           end }, -- "[ ... ]"
85         { '(', _A.tebar_content, ')', '->', '(', _A.tebar_content, ')',
86           builder = function(x)
87                local p, r = unpack(x)
88                return {tag='TFunction', p, r }
89            end } }
90
91     M.annot.ts = gg.multisequence{
92         name = 'annot.ts',
93         { 'return', _A.tebar_content, builder='TReturn' },
94         { _A.tid, builder = function(x)
95               if x[1][1]=='pass' then return {tag='TPass'}
96               else error "Bad statement type" end
97           end } }
98
99 -- TODO: add parsers for statements:
100 -- #return tebar
101 -- #alias = te
102 -- #ell = tf
103 --[[
104     M.annot.stat_annot = gg.sequence{
105         gg.list{ primary=_A.tid, separators='.' },
106         '=',
107         XXX??,
108         builder = 'Annot' }
109 --]]
110
111     return M.annot
112 end