def FunCall(): fname = yield ps.token(TOKEN.IDENTIFIER) yield ps.token(TOKEN.PAR_OPEN) found_args = yield ps.times(ActArgs, 0, 1) found_args = found_args[0] if len(found_args) > 0 else [] yield ps.token(TOKEN.PAR_CLOSE) return AST.FUNCALL(id=fname, kind=FunKind.FUNC, args=found_args)
def TupType(): yield ps.token(TOKEN.PAR_OPEN) el1 = yield Type yield ps.token(TOKEN.COMMA) el2 = yield Type yield ps.token(TOKEN.PAR_CLOSE) return AST.TUPLETYPE(a=el1, b=el2)
def StmtElif(): yield ps.token(TOKEN.ELIF) yield ps.token(TOKEN.PAR_OPEN) condition = yield Exp yield ps.token(TOKEN.PAR_CLOSE) yield ps.token(TOKEN.CURL_OPEN) contents = yield ps.many(Stmt) yield ps.token(TOKEN.CURL_CLOSE) return AST.CONDBRANCH(expr=condition, stmts=contents)
def VarDecl(): typ = yield (ps.token(TOKEN.VAR) | Type) typ = None if type(typ) == Token and typ.typ == TOKEN.VAR else typ #print(typ) varname = yield ps.token(TOKEN.IDENTIFIER) yield ps.token(TOKEN.OP_IDENTIFIER, cond=(lambda x: x == "=")) found_expr = yield Exp yield ps.token(TOKEN.SEMICOLON) return AST.VARDECL(type=typ, id=varname, expr=found_expr)
def StmtWhile(): yield ps.token(TOKEN.WHILE) yield ps.token(TOKEN.PAR_OPEN) condition = yield Exp yield ps.token(TOKEN.PAR_CLOSE) yield ps.token(TOKEN.CURL_OPEN) contents = yield ps.many(Stmt) yield ps.token(TOKEN.CURL_CLOSE) return AST.LOOP(init=None, cond=condition, update=None, stmts=contents)
def StmtIfElse(): yield ps.token(TOKEN.IF) yield ps.token(TOKEN.PAR_OPEN) condition = yield Exp yield ps.token(TOKEN.PAR_CLOSE) yield ps.token(TOKEN.CURL_OPEN) if_contents = yield ps.many(Stmt) yield ps.token(TOKEN.CURL_CLOSE) first_cond = AST.CONDBRANCH(expr=condition, stmts=if_contents) elifs = yield ps.many(StmtElif) elses = yield ps.times(StmtElse, 0, 1) return AST.IFELSE(condbranches=[first_cond, *elifs, *elses])
def ExpSubTup(): yield ps.token(TOKEN.PAR_OPEN) a = yield Exp b = yield ExpClose if b is None: return a else: return AST.TUPLE(a=a, b=b)
def FunDecl(): fname = yield ps.token(TOKEN.IDENTIFIER) yield ps.token(TOKEN.PAR_OPEN) args = yield ps.times(FArgs, 0, 1) args = args[0] if len(args) > 0 else args yield ps.token(TOKEN.PAR_CLOSE) typesig = yield ps.times(FunTypeSig, 0, 1) typesig = typesig[0] if len(typesig) > 0 else None yield ps.token(TOKEN.CURL_OPEN) decls = yield ps.many(VarDecl) found_stmts = yield ps.many1(Stmt) yield ps.token(TOKEN.CURL_CLOSE) return AST.FUNDECL(kind=FunKind.FUNC, fixity=None, id=fname, params=args, type=typesig, vardecls=decls, stmts=found_stmts)
def PrefixOpDecl(): yield ps.token(TOKEN.PREFIX) operator = yield ps.token(TOKEN.OP_IDENTIFIER) yield ps.token(TOKEN.PAR_OPEN) varname = yield ps.token(TOKEN.IDENTIFIER) yield ps.token(TOKEN.PAR_CLOSE) typesig = yield ps.times(PreFunTypeSig, 0, 1) typesig = typesig[0] if len(typesig) > 0 else None yield ps.token(TOKEN.CURL_OPEN) decls = yield ps.many(VarDecl) found_stmts = yield ps.many1(Stmt) yield ps.token(TOKEN.CURL_CLOSE) return AST.FUNDECL(kind=FunKind.PREFIX, fixity=None, id=operator, params=[varname], type=typesig, vardecls=decls, stmts=found_stmts)
def StmtFor(): yield ps.token(TOKEN.FOR) yield ps.token(TOKEN.PAR_OPEN) initial = yield ps.times(ActStmt, 0, 1) initial = initial[0] if len(initial) > 0 else None yield ps.token(TOKEN.SEMICOLON) condition = yield ps.times(Exp, 0, 1) condition = condition[0] if len(condition) > 0 else None yield ps.token(TOKEN.SEMICOLON) update = yield ps.times(ActStmt, 0, 1) update = update[0] if len(update) > 0 else None yield ps.token(TOKEN.PAR_CLOSE) yield ps.token(TOKEN.CURL_OPEN) contents = yield ps.many(Stmt) yield ps.token(TOKEN.CURL_CLOSE) return AST.LOOP(init=initial, cond=condition, update=update, stmts=contents)
def ImportListStrict(): n = yield ImportName ns = yield ps.many(ps.token(TOKEN.COMMA) >> ImportName) return [n, *ns]
def ExpTupClose(): yield ps.token(TOKEN.COMMA) b = yield Exp yield ps.token(TOKEN.PAR_CLOSE) return b
def ExpSubClose(): yield ps.token(TOKEN.PAR_CLOSE) return None
def InfFunType(): a = yield Type b = yield Type yield ps.token(TOKEN.OP_IDENTIFIER, cond=(lambda x: x == "->")) out = yield Type return AST.FUNTYPE(from_types=[a, b], to_type=out)
def InfFunTypeSig(): yield ps.token(TOKEN.OP_IDENTIFIER, cond=(lambda x: x == "::")) a = yield InfFunType return a
def IdField(): i = yield ps.token(TOKEN.IDENTIFIER) found_fields = yield ps.many(ps.token(TOKEN.ACCESSOR)) return AST.VARREF(id=i, fields=found_fields)
def Ass(): var = yield IdField yield ps.token(TOKEN.OP_IDENTIFIER, cond=(lambda x: x == "=")) expression = yield Exp return AST.ASSIGNMENT(varref=var, expr=expression)
def StmtContinue(): yield ps.token(TOKEN.CONTINUE) yield ps.token(TOKEN.SEMICOLON) return AST.CONTINUE()
def SpecificImport(): yield ps.token(TOKEN.FROM) found_name = yield ps.token(TOKEN.FILENAME) yield ps.token(TOKEN.IMPORT) found_importlist = yield ImportListStrict return AST.IMPORT(name=found_name, importlist=found_importlist)
def StmtRet(): yield ps.token(TOKEN.RETURN) found_expr = yield ps.times(Exp, 0, 1) found_expr = found_expr[0] if len(found_expr) > 0 else None yield ps.token(TOKEN.SEMICOLON) return AST.RETURN(expr=found_expr)
def StmtActSem(): a = yield ActStmt yield ps.token(TOKEN.SEMICOLON) return a
def AllImport(): yield ps.token(TOKEN.IMPORTALL) found_name = yield ps.token(TOKEN.FILENAME) return AST.IMPORT(name=found_name, importlist=None)
def PreFunTypeSig( ): # TODO maybe get rid of the typesig ones and move the :: to the decl yield ps.token(TOKEN.OP_IDENTIFIER, cond=(lambda x: x == "::")) a = yield PreFunType return a
def ExpMore(): op = yield ps.token(TOKEN.OP_IDENTIFIER) exp = yield ConvExp return [op, exp]
def ActArgs(): a = yield Exp b = yield ps.many(ps.token(TOKEN.COMMA) >> Exp) return [a, *b]
def PrefixOpExp(): op = yield ps.token(TOKEN.OP_IDENTIFIER) exp = yield ConvExp return AST.FUNCALL(kind=FunKind.PREFIX, id=op, args=[AST.DEFERREDEXPR(contents=[exp])])
def ImportName(): found_name = yield AnyId found_alias = yield ps.times(ps.token(TOKEN.AS) >> AnyId, 0, 1) found_alias = found_alias[0] if len(found_alias) > 0 else None return AST.IMPORTNAME(name=found_name, alias=found_alias)
def ExpLiteral(): tok = yield ps.token(TOKEN.INT) ^ ps.token(TOKEN.CHAR) ^ ps.token( TOKEN.STRING) ^ ps.token(TOKEN.BOOL) ^ ps.token(TOKEN.EMPTY_LIST) return tok
def StmtBreak(): yield ps.token(TOKEN.BREAK) yield ps.token(TOKEN.SEMICOLON) return AST.BREAK()
def StmtElse(): yield ps.token(TOKEN.ELSE) yield ps.token(TOKEN.CURL_OPEN) contents = yield ps.many(Stmt) yield ps.token(TOKEN.CURL_CLOSE) return AST.CONDBRANCH(expr=None, stmts=contents)