diff options
author | Mathieu Duponchelle <mathieu@centricular.com> | 2018-04-28 01:56:56 +0200 |
---|---|---|
committer | Mathieu Duponchelle <mathieu@centricular.com> | 2018-05-20 21:19:44 +0200 |
commit | ecb88380827e33161a29c5ca6f3448a6cdd557a5 (patch) | |
tree | e31280e1cf6dee24fccd716c41ccef08d437164a /mesonbuild/mparser.py | |
parent | 7e8c099387ffcdfbdc55e3ef550cf7e8ab0e848d (diff) | |
download | meson-ecb88380827e33161a29c5ca6f3448a6cdd557a5.zip meson-ecb88380827e33161a29c5ca6f3448a6cdd557a5.tar.gz meson-ecb88380827e33161a29c5ca6f3448a6cdd557a5.tar.bz2 |
Add new built-in type, dict
For now dicts are immutable, and do not expose any methods,
they however support "native" syntax such as [] lookup,
and foreach iterating, and can be printed.
Diffstat (limited to 'mesonbuild/mparser.py')
-rw-r--r-- | mesonbuild/mparser.py | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py index 8cef377..fb1058c 100644 --- a/mesonbuild/mparser.py +++ b/mesonbuild/mparser.py @@ -104,6 +104,8 @@ class Lexer: ('rparen', re.compile(r'\)')), ('lbracket', re.compile(r'\[')), ('rbracket', re.compile(r'\]')), + ('lcurl', re.compile(r'\{')), + ('rcurl', re.compile(r'\}')), ('dblquote', re.compile(r'"')), ('string', re.compile(r"'([^'\\]|(\\.))*'")), ('comma', re.compile(r',')), @@ -134,6 +136,7 @@ class Lexer: loc = 0 par_count = 0 bracket_count = 0 + curl_count = 0 col = 0 while loc < len(self.code): matched = False @@ -160,6 +163,10 @@ class Lexer: bracket_count += 1 elif tid == 'rbracket': bracket_count -= 1 + elif tid == 'lcurl': + curl_count += 1 + elif tid == 'rcurl': + curl_count -= 1 elif tid == 'dblquote': raise ParseException('Double quotes are not supported. Use single quotes.', self.getline(line_start), lineno, col) elif tid == 'string': @@ -187,7 +194,7 @@ This will become a hard error in a future Meson release.""", self.getline(line_s elif tid == 'eol' or tid == 'eol_cont': lineno += 1 line_start = loc - if par_count > 0 or bracket_count > 0: + if par_count > 0 or bracket_count > 0 or curl_count > 0: break elif tid == 'id': if match_text in self.keywords: @@ -241,6 +248,13 @@ class ArrayNode: self.colno = args.colno self.args = args +class DictNode: + def __init__(self, args): + self.subdir = args.subdir + self.lineno = args.lineno + self.colno = args.colno + self.args = args + class EmptyNode: def __init__(self, lineno, colno): self.subdir = '' @@ -340,10 +354,10 @@ class PlusAssignmentNode: self.value = value class ForeachClauseNode: - def __init__(self, lineno, colno, varname, items, block): + def __init__(self, lineno, colno, varnames, items, block): self.lineno = lineno self.colno = colno - self.varname = varname + self.varnames = varnames self.items = items self.block = block @@ -601,6 +615,10 @@ class Parser: args = self.args() self.block_expect('rbracket', block_start) return ArrayNode(args) + elif self.accept('lcurl'): + key_values = self.key_values() + self.block_expect('rcurl', block_start) + return DictNode(key_values) else: return self.e9() @@ -618,6 +636,30 @@ class Parser: return StringNode(t) return EmptyNode(self.current.lineno, self.current.colno) + def key_values(self): + s = self.statement() + a = ArgumentNode(s) + + while not isinstance(s, EmptyNode): + potential = self.current + if self.accept('comma'): + a.commas.append(potential) + a.append(s) + elif self.accept('colon'): + if not isinstance(s, StringNode): + raise ParseException('Key must be a string.', + self.getline(), s.lineno, s.colno) + a.set_kwarg(s.value, self.statement()) + potential = self.current + if not self.accept('comma'): + return a + a.commas.append(potential) + else: + a.append(s) + return a + s = self.statement() + return a + def args(self): s = self.statement() a = ArgumentNode(s) @@ -664,10 +706,17 @@ class Parser: t = self.current self.expect('id') varname = t + varnames = [t] + + if (self.accept('comma')): + t = self.current + self.expect('id') + varnames.append(t) + self.expect('colon') items = self.statement() block = self.codeblock() - return ForeachClauseNode(varname.lineno, varname.colno, varname, items, block) + return ForeachClauseNode(varname.lineno, varname.colno, varnames, items, block) def ifblock(self): condition = self.statement() |