def get_var(self, vtok, tstrm): h, tk, s = self.get_symbol(tstrm) if tk.getstr() not in "private" or tk.getstr() not in ":private": # print("Processing variable {}".format(tk)) self.values.append( ast.Variable(ast.VarHeader(s, tk, self.input), [ast.NIL], tk, self.input))
def p_expression_name(p): "expression : NAME" try: p[0] = names[p[1]] p[0] = ast.Variable(p[1], names[p[1]]) except LookupError: print("Undefined name '%s'" % p[1]) p[0] = 0
def parse_atomic_expression(self): if self.at_type(Token.LITERAL): value = self.expect_type(Token.LITERAL) result = ast.Literal(value) if isinstance(value, data.DecimalFraction): # While the infrastructure is not in place to create floats without # magic we insert a new_float invocation in the parser. result = ast.Invocation([ ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["ctrino"])))), ast.Argument(data._SELECTOR, ast.Literal(data.Operation.infix("new_float_32"))), ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)), ast.Argument(0, result) ]) return result elif self.at_type(Token.IDENTIFIER): return self.parse_variable() elif self.at_punctuation('('): self.expect_punctuation('(') result = self.parse_expression(False) self.expect_punctuation(')') return result elif self.at_punctuation('['): return self.parse_array_expression() elif self.at_punctuation('{'): return self.parse_sequence_expression() elif self.at_word('null'): self.expect_word('null') return ast.Literal(None) elif self.at_word('true'): self.expect_word('true') return ast.Literal(True) elif self.at_word('false'): self.expect_word('false') return ast.Literal(False) elif self.at_word('subject'): self.expect_word('subject') return ast.Literal(data._SUBJECT) elif self.at_word('selector'): self.expect_word('selector') return ast.Literal(data._SELECTOR) elif self.at_word('transport'): self.expect_word('transport') return ast.Literal(data._TRANSPORT) elif self.at_word('async'): self.expect_word('async') return ast.Literal(data._ASYNC) elif self.at_word('sync'): self.expect_word('sync') return ast.Literal(data._SYNC) elif self.at_word('module'): self.expect_word('module') return ast.CurrentModule() elif self.at_type(Token.QUOTE): return self.parse_quote() else: raise self.new_syntax_error()
def primary(self): if self.match('int'): #this counts for ints and longs i = self.pop().val return (ast.Literal(i)) elif self.match('float'): #counts for floats and doubles f = self.pop().val return (ast.Literal(f)) elif self.match('true'): self.pop() return ast.Literal(True) elif self.match('false'): self.pop() return (ast.Literal(False)) elif self.match('char'): return ast.Literal(self.pop().val) elif self.match('string'): return ast.Literal(self.pop().val) elif self.match_val('['): self.pop() exprList = [] e = None while not self.match_val(']'): exprList.append(e := self.expr()) if not self.match_val(','): break self.pop() if not self.match_val(']'): raise ValueError( f"you ruined the array idiot! what's wrong with you? line {self.pop().line}" ) else: self.pop() return ast.Literal(exprList) elif self.match('ident'): name = self.pop().val if (self.match_val('(')): #name is passed for error reporting arg_list = self.tuple(name) return ast.Call(name, arg_list) return ast.Variable(name) elif self.match_val('('): line_num = self.pop().line expr = self.expr() self.consume(')', f"missing ')' in '('<expr>')' on line {line_num}") return expr else: tok = self.pop() raise ValueError( f"invalid token '{tok.val}' of type '{tok.type}' in expr on line {tok.line}" )
def parse_variable(self, token, frame): """Variable parse. Productions: var symbol var symbol expression (not = FUNC, VAR, INCLUDE, MODULE) var :private symbol var :private symbol expression (not = FUNC, VAR, INCLUDE, MODULE) if there is an expression, there must be only one """ symbol = None expression = None # Edge - var token only at end if not frame: _malformed(token) # Check first for private if isinstance(frame[0], ast.LiteralReference): if frame[0].value == ":private": frame.pop(0) # Should never get here due to pre-parse, but else: raise errors.ParseError( "{}:{} Variable type only supports :private keyword." " Found {}".format(token.getsourcepos().lineno, token.getsourcepos().colno, frame[0].value)) # Should never get here due to pre-parse if not frame: _panic("{}:{} Missing symbol for {}", token) if isinstance(frame[0], ast.Symbol): symbol = frame.pop(0) # Should never get here due to pre-parse else: _panic("{}:{} Expected symbol for {}", token) # Check for expression existance if frame: if not isinstance(frame[0], self._decl_set): # TODO: Get until var, func, include or end expression = [frame.pop(0)] hdr = self._locals.get(symbol.name, None) if not hdr: _panic("{}:{} Variable {} not in symbol table", symbol.token) frame.insert(0, ast.Variable(hdr, expression, token, self.input)) return frame
def parse_for_expression(self, expect_delim): self.expect_word('for') sig = self.parse_signature() self.expect_word('in') elms = self.parse_expression(False) self.expect_word('do') body = self.parse_expression(expect_delim) thunk = ast.Lambda([ast.Method(sig, body)]) return ast.Invocation([ ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["core", "for"])))), ast.Argument(data._SELECTOR, ast.Literal(Parser._SAUSAGES)), ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)), ast.Argument(0, elms), ast.Argument(1, thunk), ])
def parse_while_expression(self, expect_delim): self.expect_word('while') cond = self.parse_expression(False) self.expect_word('do') body = self.parse_expression(expect_delim) methods = [ ast.Lambda.method(cond, data.Operation.infix('keep_running?')), ast.Lambda.method(body, data.Operation.infix('run!')) ] return ast.Invocation([ ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["core", "while"])))), ast.Argument(data._SELECTOR, ast.Literal(Parser._SAUSAGES)), ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)), ast.Argument(0, ast.Lambda(methods)), ])
def parse_toplevel_declaration(self, annots): self.expect_word('def') subject = None is_prefix = False name = None allow_extra = False if self.at_type(Token.IDENTIFIER): # def <ident> ident = self.current().value name = self.expect_type(Token.IDENTIFIER) if self.at_punctuation(':='): # def <ident> := self.expect_punctuation(':=') value = self.parse_expression(True) return ast.NamespaceDeclaration(annots, name, value) else: if self.at_punctuation('('): # def <ident> ( subject = ast.Parameter(name, [data._SUBJECT], ast.Guard.eq(ast.Variable(name.shift_back()))) is_async = ast.Parameter(None, [data._TRANSPORT], ast.Guard.eq(ast.Literal(data._SYNC))) (params, operation, allow_extra, reified) = self.parse_parameters(Parser._SAUSAGES) body = self.parse_method_tail(True) selector = self.name_as_selector(operation) signature = ast.Signature([subject, selector, is_async] + params, allow_extra, reified) return ast.FunctionDeclaration(name, ast.Method(signature, body)) else: # def <ident> ... subject = ast.Parameter(name, [data._SUBJECT], ast.Guard.any()) elif self.at_word('type'): # def type <atomic> is <atomic> self.expect_word('type') subtype = self.parse_atomic_expression() self.expect_word('is') supertype = self.parse_atomic_expression() self.expect_statement_delimiter(True) return ast.IsDeclaration(subtype, supertype) elif self.at_type(Token.OPERATION): # def <operation> ... (name, is_async) = self.expect_type(Token.OPERATION) subject = self.parse_subject() is_prefix = True else: # def (<parameter>) subject = self.parse_subject() signature = self.parse_functino_signature([subject], is_prefix, name) body = self.parse_method_tail(True) stage = self.get_subject_stage(subject) return ast.MethodDeclaration(stage + 1, annots, ast.Method(signature, body))
def parse_when_expression(self, expect_delim): self.expect_word('when') self.expect_word('def') sig = self.parse_signature() self.expect_punctuation(':=') value = self.parse_expression(False) self.expect_word('do') body = self.parse_expression(expect_delim) thunk = ast.Lambda([ast.Method(sig, body)]) return ast.Invocation([ ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["core", "when_def"])))), ast.Argument(data._SELECTOR, ast.Literal(Parser._SAUSAGES)), ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)), ast.Argument(0, value), ast.Argument(1, thunk), ])
def parse_type_members(self, holder): result = [] if not self.at_punctuation('{'): return result self.expect_punctuation('{') try: # Change the default subject guard for the case where none is explicitly # given to the enclosing type. old_default = self.default_subject_guard self.default_subject_guard = ast.Guard.is_(ast.Variable(holder)) while not self.at_punctuation('}'): member = self.parse_type_member() result.append(member) finally: # Remember to pop the default guard off again. self.default_subject_guard = old_default self.expect_punctuation('}') return result
def parse_if_expression(self, expect_delim): self.expect_word('if') cond = self.parse_expression(False) self.expect_word('then') then_part = self.parse_expression(expect_delim) if self.at_word('else'): self.expect_word('else') else_part = self.parse_expression(expect_delim) else: else_part = ast.Literal(None) methods = [ ast.Lambda.method(then_part, data.Operation.infix('then!')), ast.Lambda.method(else_part, data.Operation.infix('else!')) ] args = [ ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["core", "if"])))), ast.Argument(data._SELECTOR, ast.Literal(Parser._SAUSAGES)), ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)), ast.Argument(0, cond), ast.Argument(1, ast.Lambda(methods)) ] result = ast.Invocation(args) return result
('!', 1, opAssoc.RIGHT, lambda t: ast.Negate(t[0][1]))]) mem_lvalue = ("*" + expr).setParseAction(lambda t: ast.RefLoc(t[1])) io_lvalue = Keyword("IO").setParseAction(lambda t: ast.Io()) stack = (Keyword("stack") + single_letter).setParseAction(lambda t: ast.Stack(t[1])) tape = (Keyword("tape") + single_letter).setParseAction(lambda t: ast.Tape(t[1])) special_loc << ('[' + MatchFirst([io_lvalue, stack, tape]) + ']').setParseAction(lambda t: t[1]) lvariable = identifier.copy().setParseAction(lambda t: ast.Variable(t[0])) struct_access << ( type_identifier + '@' + expr + '.' + identifier).setParseAction(lambda t: ast.StructAccess(t[0], t[2], t[4])) # == LVALUES == lvalue = MatchFirst([lvariable, mem_lvalue, special_loc, struct_access]) declarevar = (Keyword('var') + identifier + Optional(Literal(':=').suppress() + expr, default=None) ).setParseAction(lambda t: ast.DeclareVar(t[1], t[2])) declarefn = (Keyword('declare') + identifier + Optional(Keyword('returns').setParseAction(lambda t: True), default = False))\ .setParseAction(lambda t: ast.DeclareFunction(t[1], t[2]))
def parse_variable(self): ident = self.expect_type(Token.IDENTIFIER) stage_index = ident.stage stage = self.module.get_or_create_fragment(stage_index) return ast.Variable(ident)
def p_variable(self, p): """ variable : ID | access """ p[0] = ast.Variable(p[1], p.lexer.lexer.lineno)
def p_id_transpose(self, p): """ expression : ID TRANSPOSE """ position = p.lexer.lexer.lineno p[0] = ast.Transposition(ast.Variable(p[1], position), position)
def p_expression_id(self, p): """expression : ID""" p[0] = ast.Variable(p[1], p.lexer.lexer.lineno)