diff --git a/bsc/astgen/AST.py b/bsc/astgen/AST.py index d3b7ef6..0ee0221 100644 --- a/bsc/astgen/AST.py +++ b/bsc/astgen/AST.py @@ -622,6 +622,22 @@ def __eq__(self, other): return str(self.expr) == str(other.expr) return False +class ResultType: + def __init__(self, type, pos): + self.type = type + self.pos = pos + + def __str__(self): + return f"!{self.type}" + + def __repr__(self): + return str(self) + + def __eq__(self, other): + if isinstance(other, ResultType): + return self.type == other.type + return False + class OptionType: def __init__(self, type, pos): self.type = type @@ -657,7 +673,7 @@ def __eq__(self, other): return str(self.size) == str(other.size) and self.type == other.type return False -class MapType: +class TableType: def __init__(self, k_type, v_type, pos): self.k_type = k_type self.v_type = v_type @@ -670,7 +686,7 @@ def __repr__(self): return str(self) def __eq__(self, other): - if isinstance(other, MapType): + if isinstance(other, TableType): return self.k_type == other.k_type and self.v_type == other.v_type return False diff --git a/bsc/astgen/__init__.py b/bsc/astgen/__init__.py index d4623f7..62dec3a 100644 --- a/bsc/astgen/__init__.py +++ b/bsc/astgen/__init__.py @@ -130,9 +130,15 @@ def fn_decl(self, *nodes): else: args = [] ret_type = nodes[6] - if isinstance(ret_type, BlockExpr - ) or isinstance(ret_type, Token) or not ret_type: + is_result = isinstance(ret_type, Token) and str(ret_type) == "!" + if is_result: + ret_type = nodes[7] + if isinstance(ret_type, + BlockExpr) or isinstance(ret_type, + Token) or (not ret_type): ret_type = self.ctx.void_type + if is_result: + ret_type = ResultType(ret_type, self.mkpos(nodes[6])) stmts = [] if len(nodes) == 8: stmts = nodes[-1] @@ -533,7 +539,7 @@ def access_modifier(self, *nodes): return AccessModifier.private # Types - def user_type(self, *names): + def user_type_decl(self, *names): left = names[0] if isinstance(left, Ident): match left.name: @@ -555,20 +561,20 @@ def user_type(self, *names): return BasicType(left, left.pos) return BasicType(left, left.pos) - def option_type(self, *nodes): + def option_type_decl(self, *nodes): return OptionType(nodes[1], self.mkpos(nodes[0])) - def array_type(self, *nodes): + def array_type_decl(self, *nodes): has_size = not isinstance(nodes[1], Token) size = nodes[1] if has_size else None return ArrayType( size, nodes[3 if has_size else 2], self.mkpos(nodes[0]) ) - def map_type(self, *nodes): - return MapType(nodes[1], nodes[3], self.mkpos(nodes[0])) + def table_type_decl(self, *nodes): + return TableType(nodes[1], nodes[3], self.mkpos(nodes[0])) - def sum_type(self, *nodes): + def sum_type_decl(self, *nodes): types = list(filter(lambda node: not isinstance(node, Token), nodes)) return SumType(types, nodes[0].pos) diff --git a/bsc/astgen/grammar.lark b/bsc/astgen/grammar.lark index 5fcc5ca..1c5c3b6 100644 --- a/bsc/astgen/grammar.lark +++ b/bsc/astgen/grammar.lark @@ -34,30 +34,30 @@ use_tree: path_expr DOUBLE_COLON MUL mod_decl: [access_modifier] KW_MOD NAME (LBRACE decl* RBRACE | SEMICOLON) -const_decl: [access_modifier] KW_CONST NAME [COLON type] OP_ASSIGN expr SEMICOLON +const_decl: [access_modifier] KW_CONST NAME [COLON type_decl] OP_ASSIGN expr SEMICOLON var_decl: [access_modifier] KW_VAR var_ident (COMMA var_ident)* OP_ASSIGN expr SEMICOLON -var_ident: NAME [COLON type] +var_ident: NAME [COLON type_decl] enum_decl: [access_modifier] KW_ENUM NAME LBRACE enum_fields decl* RBRACE enum_fields: enum_field (COMMA enum_field)* 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] SEMICOLON +class_field: [access_modifier] NAME COLON type_decl [OP_ASSIGN expr] SEMICOLON -fn_decl: [access_modifier] KW_FN NAME LPAREN [fn_args] RPAREN [BANG | type] (SEMICOLON | block) +fn_decl: [access_modifier] KW_FN NAME LPAREN [fn_args] RPAREN [BANG? type_decl] (SEMICOLON | block) fn_args: (KW_SELF | fn_arg) (COMMA fn_arg)* -fn_arg: NAME COLON type [OP_ASSIGN expr] +fn_arg: NAME COLON type_decl [OP_ASSIGN expr] access_modifier: KW_PUB [LPAREN KW_PKG RPAREN] | KW_PROT -?type: path_expr -> user_type - | QUESTION type -> option_type - | LBRACKET expr? RBRACKET type -> array_type - | LBRACE type COLON type RBRACE -> map_type - | type PIPE type (PIPE type)* -> sum_type - | LPAREN type COMMA type (COMMA type)* RPAREN -> tuple_type +?type_decl: path_expr -> user_type_decl + | QUESTION type_decl -> option_type_decl + | LBRACKET expr? RBRACKET type_decl -> array_type_decl + | LBRACE type_decl COLON type_decl RBRACE -> table_type_decl + | type_decl PIPE type_decl (PIPE type_decl)* -> sum_type_decl + | LPAREN type_decl COMMA type_decl (COMMA type_decl)* RPAREN -> tuple_type_decl // Statements @@ -97,7 +97,7 @@ unary_expr: unary_op primary_expr | primary_expr | block_expr | expr LPAREN [expr (COMMA expr)*] RPAREN -> call_expr | LPAREN expr (COMMA expr)* RPAREN -> tuple_literal - | LBRACE expr COLON expr (COMMA expr COLON expr)* RBRACE -> map_literal + | LBRACE expr COLON expr (COMMA expr COLON expr)* RBRACE -> table_literal | [HASH] LBRACKET [expr (COMMA expr)*] RBRACKET -> array_literal | DOT NAME -> enum_literal | path_expr diff --git a/bsc/sym.py b/bsc/sym.py index fcc8974..dd811fc 100644 --- a/bsc/sym.py +++ b/bsc/sym.py @@ -115,7 +115,7 @@ class TypeKind(IntEnum): float = auto() string = auto() array = auto() - map = auto() + table = auto() tuple = auto() sumtype = auto() enum = auto() @@ -141,8 +141,8 @@ def __str__(self): return "string" case TypeKind.array: return "array" - case TypeKind.map: - return "map" + case TypeKind.table: + return "table" case TypeKind.tuple: return "tuple" case TypeKind.sumtype: diff --git a/tests/main.bs b/tests/main.bs index 7a47c6c..5c14f96 100644 --- a/tests/main.bs +++ b/tests/main.bs @@ -9,7 +9,7 @@ const float_num = 0.5e4; const f = 1.0 / 2.0; const i = 1 / 2; -fn main() void { +fn main() !void { print("hello"); const XXX = dec_num; }