From bd25ef71f2be3d0ac7210150922e3746943b31fb Mon Sep 17 00:00:00 2001 From: Jose Mendoza <56417208+StunxFS@users.noreply.github.com> Date: Mon, 10 Jun 2024 22:25:08 +0000 Subject: [PATCH] wip --- bsc/AST.py | 43 +++++++++++++++++++++++++++++++++++++++++++ bsc/astgen.py | 25 ++++++++++++++----------- bsc/grammar.lark | 3 ++- bsc/sema.py | 18 ++++++++++++++++++ bsc/sym.py | 3 +++ 5 files changed, 80 insertions(+), 12 deletions(-) diff --git a/bsc/AST.py b/bsc/AST.py index 13fe41a..4157c43 100644 --- a/bsc/AST.py +++ b/bsc/AST.py @@ -76,6 +76,7 @@ def __init__( self.is_method = is_method self.ret_type = ret_type self.stmts = stmts + self.has_body = stmts != None self.is_main = is_main self.sym = None self.pos = pos @@ -504,6 +505,13 @@ def __str__(self): def __repr__(self): return str(self) + def __eq__(self, other): + if isinstance(other, BasicType): + if self.typesym: + return self.typesym == other.typesym + return str(self.expr) == str(other.expr) + return False + class OptionType: def __init__(self, type, pos): self.type = type @@ -515,6 +523,11 @@ def __str__(self): def __repr__(self): return str(self) + def __eq__(self, other): + if isinstance(other, OptionType): + return self.type == other.type + return False + class ArrayType: def __init__(self, size, type, pos): self.size = size @@ -529,6 +542,11 @@ def __str__(self): def __repr__(self): return str(self) + def __eq__(self, other): + if isinstance(other, ArrayType): + return str(self.size) == str(other.size) and self.type == other.type + return False + class MapType: def __init__(self, k_type, v_type, pos): self.k_type = k_type @@ -541,6 +559,11 @@ def __str__(self): def __repr__(self): return str(self) + def __eq__(self, other): + if isinstance(other, MapType): + return self.k_type == other.k_type and self.v_type == other.v_type + return False + class SumType: def __init__(self, types, pos): self.types = types @@ -552,6 +575,16 @@ def __str__(self): def __repr__(self): return str(self) + def __eq__(self, other): + if isinstance(other, SumType): + if len(self.types) != len(other.types): + return False + for i,t in enumerate(self.types): + if t != other.types[i]: + return False + return True + return False + class TupleType: def __init__(self, types, pos): self.types = types @@ -562,3 +595,13 @@ def __str__(self): def __repr__(self): return str(self) + + def __eq__(self, other): + if isinstance(other, TupleType): + if len(self.types) != len(other.types): + return False + for i,t in enumerate(self.types): + if t != other.types[i]: + return False + return True + return False diff --git a/bsc/astgen.py b/bsc/astgen.py index 9148bd3..ee12895 100644 --- a/bsc/astgen.py +++ b/bsc/astgen.py @@ -93,21 +93,24 @@ def fn_decl(self, *nodes): access_modifier = self.get_access_modifier(nodes[0]) name = nodes[2].name args = nodes[4] - if isinstance(args, Token): - is_method = False - args = [] + is_method = False + if args: + if isinstance(args, Token): + args = [] + else: + is_method = args[0] + args = list(args[1]) else: - is_method = args[0] - args = list(args[1]) - ret_type = nodes[5] + args = [] + ret_type = nodes[6] if isinstance(ret_type, BlockStmt ) or isinstance(ret_type, Token) or not ret_type: ret_type = self.ctx.void_type stmts = [] - if not isinstance(nodes[-1], Token): + if nodes[-1] == None: + stmts = None + else: stmts = nodes[-1] - if stmts == ret_type: # no body - stmts = None return FnDecl( access_modifier, name, args, is_method, ret_type, stmts, name == "main" and self.file == self.ctx.prefs.input, pos @@ -123,8 +126,8 @@ def fn_arg(self, *nodes): def fn_body(self, *nodes): stmts = [] if len(nodes) != 2: - stmts = nodes[1:-1] - return BlockStmt(stmts, self.mkpos(nodes[0])) + stmts = list(nodes[1:-1]) + return stmts # Statements def var_decl(self, *nodes): diff --git a/bsc/grammar.lark b/bsc/grammar.lark index 1acd361..53573f8 100644 --- a/bsc/grammar.lark +++ b/bsc/grammar.lark @@ -45,7 +45,7 @@ enum_field: NAME [OP_ASSIGN expr] class_decl: [access_modifier] KW_CLASS NAME LBRACE (class_field | decl)* RBRACE class_field: [access_modifier] NAME COLON type [OP_ASSIGN expr] -fn_decl: [access_modifier] KW_FN NAME LPAREN fn_args? RPAREN [BANG | type] fn_body? +fn_decl: [access_modifier] KW_FN NAME LPAREN [fn_args] RPAREN [BANG | type] [fn_body] fn_args: (KW_SELF | fn_arg) (COMMA fn_arg)* fn_arg: NAME COLON type [OP_ASSIGN expr] fn_body: LBRACE stmt* RBRACE @@ -70,6 +70,7 @@ primitive_type: "any" ?stmt: expr | var_decl + | const_decl | assignment | block | KW_WHILE LPAREN expr RPAREN stmt -> while_stmt diff --git a/bsc/sema.py b/bsc/sema.py index 24b5a87..ea121b3 100644 --- a/bsc/sema.py +++ b/bsc/sema.py @@ -84,8 +84,26 @@ def check_fn_decl(self, decl): decl.access_modifier, decl.name, [], self.open_scope() ) self.add_sym(decl.sym, decl.pos) + if decl.has_body: + self.check_stmts(decl.stmts) self.close_scope() return + if decl.has_body: + self.check_stmts(decl.stmts) + + def check_var_decl(self, stmt): + for left in stmt.lefts: + print(left) + + ## === Statements =================================== + + def check_stmts(self, stmts): + for stmt in stmts: + self.check_stmt(stmt) + + def check_stmt(self, stmt): + if isinstance(stmt, VarDecl): + self.check_var_decl(stmt) ## === Utilities ==================================== diff --git a/bsc/sym.py b/bsc/sym.py index 3bbd243..cdac616 100644 --- a/bsc/sym.py +++ b/bsc/sym.py @@ -64,6 +64,9 @@ def codegen_qualname(self, sep = "."): return f"{self.parent.codegen_qualname(sep)}{sep}{self.name}" return self.name + def __eq__(self, other): + return str(self) == str(other) + def __repr__(self): return str(self)