diff options
| author | gingerBill <bill@gingerbill.org> | 2018-01-17 19:07:38 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2018-01-17 19:07:38 +0000 |
| commit | 419ab6f00c5396c1296a78e931693ba38d7ea102 (patch) | |
| tree | ab4f8cfe76b023c568257260e3adbe28f37d97d9 /src/parser.cpp | |
| parent | 5558b55e9f1f7b80c052bc803fd43f317849f98c (diff) | |
Named return value act as variables; Code reorganization
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 556 |
1 files changed, 10 insertions, 546 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 0c47bf360..e0c919667 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,543 +1,3 @@ -struct AstNode; -struct Scope; -struct Entity; -struct DeclInfo; - -enum ParseFileError { - ParseFile_None, - - ParseFile_WrongExtension, - ParseFile_InvalidFile, - ParseFile_EmptyFile, - ParseFile_Permission, - ParseFile_NotFound, - ParseFile_InvalidToken, - - ParseFile_Count, -}; - -struct CommentGroup { - Array<Token> list; // Token_Comment -}; - - -enum ImportedFileKind { - ImportedFile_Normal, - ImportedFile_Shared, - ImportedFile_Init, -}; - -struct ImportedFile { - ImportedFileKind kind; - String path; - String rel_path; - TokenPos pos; // import - isize index; -}; - - -struct AstFile { - isize id; - String fullpath; - gbArena arena; - Tokenizer tokenizer; - Array<Token> tokens; - isize curr_token_index; - Token curr_token; - Token prev_token; // previous non-comment - - // >= 0: In Expression - // < 0: In Control Clause - // NOTE(bill): Used to prevent type literals in control clauses - isize expr_level; - bool allow_range; // NOTE(bill): Ranges are only allowed in certain cases - bool in_foreign_block; - bool allow_type; - isize when_level; - - Array<AstNode *> decls; - ImportedFileKind file_kind; - bool is_global_scope; - Array<AstNode *> imports_and_exports; // 'import' 'using import' 'export' - - - AstNode * curr_proc; - isize scope_level; - Scope * scope; // NOTE(bill): Created in checker - DeclInfo * decl_info; // NOTE(bill): Created in checker - - - CommentGroup lead_comment; // Comment (block) before the decl - CommentGroup line_comment; // Comment after the semicolon - CommentGroup docs; // current docs - Array<CommentGroup> comments; // All the comments! - - -#define PARSER_MAX_FIX_COUNT 6 - isize fix_count; - TokenPos fix_prev_pos; -}; - - -struct Parser { - String init_fullpath; - Array<AstFile *> files; - Array<ImportedFile> imports; - isize total_token_count; - isize total_line_count; - gbMutex file_add_mutex; - gbMutex file_decl_mutex; -}; - -enum ProcInlining { - ProcInlining_none = 0, - ProcInlining_inline = 1, - ProcInlining_no_inline = 2, -}; - -enum ProcTag { - ProcTag_bounds_check = 1<<0, - ProcTag_no_bounds_check = 1<<1, - ProcTag_require_results = 1<<4, -}; - -enum ProcCallingConvention { - ProcCC_Invalid = 0, - ProcCC_Odin, - ProcCC_Contextless, - ProcCC_CDecl, - ProcCC_StdCall, - ProcCC_FastCall, - - // TODO(bill): Add extra calling conventions - // ProcCC_VectorCall, - // ProcCC_ClrCall, - - ProcCC_ForeignBlockDefault = -1, -}; - -enum StmtStateFlag { - StmtStateFlag_bounds_check = 1<<0, - StmtStateFlag_no_bounds_check = 1<<1, -}; - -enum FieldFlag { - FieldFlag_NONE = 0, - FieldFlag_ellipsis = 1<<0, - FieldFlag_using = 1<<1, - FieldFlag_no_alias = 1<<2, - FieldFlag_c_vararg = 1<<3, - FieldFlag_in = 1<<4, - - // FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_in, - FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg, - FieldFlag_Struct = FieldFlag_using, -}; - -enum StmtAllowFlag { - StmtAllowFlag_None = 0, - StmtAllowFlag_In = 1<<0, - StmtAllowFlag_Label = 1<<1, -}; - - - -Array<AstNode *> make_ast_node_array(AstFile *f, isize init_capacity = 8) { - Array<AstNode *> a; - array_init(&a, heap_allocator(), init_capacity); - return a; -} - - -// NOTE(bill): This massive define is so it is possible to create a discriminated union (and extra debug info) -// for the AstNode. I personally prefer discriminated unions over subtype polymorphism as I can preallocate -// all the nodes and even memcpy in a different kind of node -#define AST_NODE_KINDS \ - AST_NODE_KIND(Ident, "identifier", struct { \ - Token token; \ - Entity *entity; \ - }) \ - AST_NODE_KIND(Implicit, "implicit", Token) \ - AST_NODE_KIND(Undef, "undef", Token) \ - AST_NODE_KIND(BasicLit, "basic literal", struct { \ - Token token; \ - }) \ - AST_NODE_KIND(BasicDirective, "basic directive", struct { \ - Token token; \ - String name; \ - }) \ - AST_NODE_KIND(Ellipsis, "ellipsis", struct { \ - Token token; \ - AstNode *expr; \ - }) \ - AST_NODE_KIND(ProcGroup, "procedure group", struct { \ - Token token; \ - Token open; \ - Token close; \ - Array<AstNode *> args; \ - }) \ - AST_NODE_KIND(ProcLit, "procedure literal", struct { \ - AstNode *type; \ - AstNode *body; \ - u64 tags; \ - ProcInlining inlining; \ - }) \ - AST_NODE_KIND(CompoundLit, "compound literal", struct { \ - AstNode *type; \ - Array<AstNode *> elems; \ - Token open, close; \ - }) \ -AST_NODE_KIND(_ExprBegin, "", i32) \ - AST_NODE_KIND(BadExpr, "bad expression", struct { Token begin, end; }) \ - AST_NODE_KIND(TagExpr, "tag expression", struct { Token token, name; AstNode *expr; }) \ - AST_NODE_KIND(RunExpr, "run expression", struct { Token token, name; AstNode *expr; }) \ - AST_NODE_KIND(UnaryExpr, "unary expression", struct { Token op; AstNode *expr; }) \ - AST_NODE_KIND(BinaryExpr, "binary expression", struct { Token op; AstNode *left, *right; } ) \ - AST_NODE_KIND(ParenExpr, "parentheses expression", struct { AstNode *expr; Token open, close; }) \ - AST_NODE_KIND(SelectorExpr, "selector expression", struct { Token token; AstNode *expr, *selector; }) \ - AST_NODE_KIND(IndexExpr, "index expression", struct { AstNode *expr, *index; Token open, close; }) \ - AST_NODE_KIND(DerefExpr, "dereference expression", struct { Token op; AstNode *expr; }) \ - AST_NODE_KIND(SliceExpr, "slice expression", struct { \ - AstNode *expr; \ - Token open, close; \ - Token interval; \ - AstNode *low, *high; \ - }) \ - AST_NODE_KIND(CallExpr, "call expression", struct { \ - AstNode * proc; \ - Array<AstNode *> args; \ - Token open; \ - Token close; \ - Token ellipsis; \ - }) \ - AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \ - AST_NODE_KIND(TernaryExpr, "ternary expression", struct { AstNode *cond, *x, *y; }) \ - AST_NODE_KIND(TypeAssertion, "type assertion", struct { AstNode *expr; Token dot; AstNode *type; }) \ - AST_NODE_KIND(TypeCast, "type cast", struct { Token token; AstNode *type, *expr; }) \ -AST_NODE_KIND(_ExprEnd, "", i32) \ -AST_NODE_KIND(_StmtBegin, "", i32) \ - AST_NODE_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \ - AST_NODE_KIND(EmptyStmt, "empty statement", struct { Token token; }) \ - AST_NODE_KIND(ExprStmt, "expression statement", struct { AstNode *expr; } ) \ - AST_NODE_KIND(TagStmt, "tag statement", struct { \ - Token token; \ - Token name; \ - AstNode *stmt; \ - }) \ - AST_NODE_KIND(AssignStmt, "assign statement", struct { \ - Token op; \ - Array<AstNode *> lhs, rhs; \ - }) \ - AST_NODE_KIND(IncDecStmt, "increment decrement statement", struct { \ - Token op; \ - AstNode *expr; \ - }) \ -AST_NODE_KIND(_ComplexStmtBegin, "", i32) \ - AST_NODE_KIND(BlockStmt, "block statement", struct { \ - Array<AstNode *> stmts; \ - Token open, close; \ - }) \ - AST_NODE_KIND(IfStmt, "if statement", struct { \ - Token token; \ - AstNode *init; \ - AstNode *cond; \ - AstNode *body; \ - AstNode *else_stmt; \ - }) \ - AST_NODE_KIND(WhenStmt, "when statement", struct { \ - Token token; \ - AstNode *cond; \ - AstNode *body; \ - AstNode *else_stmt; \ - bool is_cond_determined; \ - bool determined_cond; \ - }) \ - AST_NODE_KIND(ReturnStmt, "return statement", struct { \ - Token token; \ - Array<AstNode *> results; \ - }) \ - AST_NODE_KIND(ForStmt, "for statement", struct { \ - Token token; \ - AstNode *label; \ - AstNode *init; \ - AstNode *cond; \ - AstNode *post; \ - AstNode *body; \ - }) \ - AST_NODE_KIND(RangeStmt, "range statement", struct { \ - Token token; \ - AstNode *label; \ - AstNode *val0; \ - AstNode *val1; \ - Token in_token; \ - AstNode *expr; \ - AstNode *body; \ - }) \ - AST_NODE_KIND(CaseClause, "case clause", struct { \ - Token token; \ - Array<AstNode *> list; \ - Array<AstNode *> stmts; \ - Entity *implicit_entity; \ - }) \ - AST_NODE_KIND(SwitchStmt, "switch statement", struct { \ - Token token; \ - AstNode *label; \ - AstNode *init; \ - AstNode *tag; \ - AstNode *body; \ - }) \ - AST_NODE_KIND(TypeSwitchStmt, "type switch statement", struct { \ - Token token; \ - AstNode *label; \ - AstNode *tag; \ - AstNode *body; \ - }) \ - AST_NODE_KIND(DeferStmt, "defer statement", struct { Token token; AstNode *stmt; }) \ - AST_NODE_KIND(BranchStmt, "branch statement", struct { Token token; AstNode *label; }) \ - AST_NODE_KIND(UsingStmt, "using statement", struct { \ - Token token; \ - Array<AstNode *> list; \ - }) \ - AST_NODE_KIND(UsingInStmt, "using in statement", struct { \ - Token using_token; \ - Array<AstNode *> list; \ - Token in_token; \ - AstNode *expr; \ - }) \ - AST_NODE_KIND(AsmOperand, "assembly operand", struct { \ - Token string; \ - AstNode *operand; \ - }) \ - AST_NODE_KIND(AsmStmt, "assembly statement", struct { \ - Token token; \ - bool is_volatile; \ - Token open, close; \ - Token code_string; \ - AstNode *output_list; \ - AstNode *input_list; \ - AstNode *clobber_list; \ - isize output_count, input_count, clobber_count; \ - }) \ - AST_NODE_KIND(PushContext, "context <- statement", struct { \ - Token token; \ - AstNode *expr; \ - AstNode *body; \ - }) \ -AST_NODE_KIND(_ComplexStmtEnd, "", i32) \ -AST_NODE_KIND(_StmtEnd, "", i32) \ -AST_NODE_KIND(_DeclBegin, "", i32) \ - AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \ - AST_NODE_KIND(ForeignBlockDecl, "foreign block declaration", struct { \ - Token token; \ - AstNode * foreign_library; \ - Token open, close; \ - Array<AstNode *> decls; \ - Array<AstNode *> attributes; \ - bool been_handled; \ - CommentGroup docs; \ - }) \ - AST_NODE_KIND(Label, "label", struct { \ - Token token; \ - AstNode *name; \ - }) \ - AST_NODE_KIND(ValueDecl, "value declaration", struct { \ - Array<AstNode *> names; \ - AstNode * type; \ - Array<AstNode *> values; \ - bool is_using; \ - bool is_mutable; \ - bool been_handled; \ - Array<AstNode *> attributes; \ - CommentGroup docs; \ - CommentGroup comment; \ - }) \ - AST_NODE_KIND(ImportDecl, "import declaration", struct { \ - AstFile *file; \ - Token token; \ - Token relpath; \ - String fullpath; \ - Token import_name; \ - bool is_using; \ - bool been_handled; \ - Array<AstNode *> using_in_list; \ - CommentGroup docs; \ - CommentGroup comment; \ - }) \ - AST_NODE_KIND(ExportDecl, "export declaration", struct { \ - AstFile *file; \ - Token token; \ - Token relpath; \ - String fullpath; \ - bool been_handled; \ - Array<AstNode *> using_in_list; \ - CommentGroup docs; \ - CommentGroup comment; \ - }) \ - AST_NODE_KIND(ForeignImportDecl, "foreign import declaration", struct { \ - Token token; \ - Token filepath; \ - Token library_name; \ - String base_dir; \ - String collection_name; \ - String fullpath; \ - bool been_handled; \ - CommentGroup docs; \ - CommentGroup comment; \ - }) \ -AST_NODE_KIND(_DeclEnd, "", i32) \ - AST_NODE_KIND(Attribute, "attribute", struct { \ - Token token; \ - AstNode *type; \ - Array<AstNode *> elems; \ - Token open, close; \ - }) \ - AST_NODE_KIND(Field, "field", struct { \ - Array<AstNode *> names; \ - AstNode * type; \ - AstNode * default_value; \ - u32 flags; \ - CommentGroup docs; \ - CommentGroup comment; \ - }) \ - AST_NODE_KIND(FieldList, "field list", struct { \ - Token token; \ - Array<AstNode *> list; \ - }) \ - AST_NODE_KIND(UnionField, "union field", struct { \ - AstNode *name; \ - AstNode *list; \ - }) \ -AST_NODE_KIND(_TypeBegin, "", i32) \ - AST_NODE_KIND(TypeType, "type", struct { \ - Token token; \ - AstNode *specialization; \ - }) \ - AST_NODE_KIND(HelperType, "helper type", struct { \ - Token token; \ - AstNode *type; \ - }) \ - AST_NODE_KIND(AliasType, "alias type", struct { \ - Token token; \ - AstNode *type; \ - }) \ - AST_NODE_KIND(PolyType, "polymorphic type", struct { \ - Token token; \ - AstNode *type; \ - AstNode *specialization; \ - }) \ - AST_NODE_KIND(ProcType, "procedure type", struct { \ - Token token; \ - AstNode *params; \ - AstNode *results; \ - u64 tags; \ - ProcCallingConvention calling_convention; \ - bool generic; \ - }) \ - AST_NODE_KIND(PointerType, "pointer type", struct { \ - Token token; \ - AstNode *type; \ - }) \ - AST_NODE_KIND(ArrayType, "array type", struct { \ - Token token; \ - AstNode *count; \ - AstNode *elem; \ - }) \ - AST_NODE_KIND(DynamicArrayType, "dynamic array type", struct { \ - Token token; \ - AstNode *elem; \ - }) \ - AST_NODE_KIND(StructType, "struct type", struct { \ - Token token; \ - Array<AstNode *> fields; \ - isize field_count; \ - AstNode * polymorphic_params; \ - bool is_packed; \ - bool is_raw_union; \ - AstNode * align; \ - }) \ - AST_NODE_KIND(UnionType, "union type", struct { \ - Token token; \ - Array<AstNode *> variants; \ - AstNode * align; \ - }) \ - AST_NODE_KIND(EnumType, "enum type", struct { \ - Token token; \ - AstNode * base_type; \ - Array<AstNode *> fields; /* FieldValue */ \ - }) \ - AST_NODE_KIND(BitFieldType, "bit field type", struct { \ - Token token; \ - Array<AstNode *> fields; /* FieldValue with : */ \ - AstNode * align; \ - }) \ - AST_NODE_KIND(MapType, "map type", struct { \ - Token token; \ - AstNode *count; \ - AstNode *key; \ - AstNode *value; \ - }) \ -AST_NODE_KIND(_TypeEnd, "", i32) - -enum AstNodeKind { - AstNode_Invalid, -#define AST_NODE_KIND(_kind_name_, ...) GB_JOIN2(AstNode_, _kind_name_), - AST_NODE_KINDS -#undef AST_NODE_KIND - AstNode_Count, -}; - -String const ast_node_strings[] = { - {cast(u8 *)"invalid node", gb_size_of("invalid node")}, -#define AST_NODE_KIND(_kind_name_, name, ...) {cast(u8 *)name, gb_size_of(name)-1}, - AST_NODE_KINDS -#undef AST_NODE_KIND -}; - -#define AST_NODE_KIND(_kind_name_, name, ...) typedef __VA_ARGS__ GB_JOIN2(AstNode, _kind_name_); - AST_NODE_KINDS -#undef AST_NODE_KIND - -struct AstNode { - AstNodeKind kind; - u32 stmt_state_flags; - AstFile * file; - Scope * scope; - - union { -#define AST_NODE_KIND(_kind_name_, name, ...) GB_JOIN2(AstNode, _kind_name_) _kind_name_; - AST_NODE_KINDS -#undef AST_NODE_KIND - }; -}; - - -#define ast_node(n_, Kind_, node_) GB_JOIN2(AstNode, Kind_) *n_ = &(node_)->Kind_; GB_ASSERT((node_)->kind == GB_JOIN2(AstNode_, Kind_)) -#define case_ast_node(n_, Kind_, node_) case GB_JOIN2(AstNode_, Kind_): { ast_node(n_, Kind_, node_); -#ifndef case_end -#define case_end } break; -#endif - - -gb_inline bool is_ast_node_expr(AstNode *node) { - return gb_is_between(node->kind, AstNode__ExprBegin+1, AstNode__ExprEnd-1); -} -gb_inline bool is_ast_node_stmt(AstNode *node) { - return gb_is_between(node->kind, AstNode__StmtBegin+1, AstNode__StmtEnd-1); -} -gb_inline bool is_ast_node_complex_stmt(AstNode *node) { - return gb_is_between(node->kind, AstNode__ComplexStmtBegin+1, AstNode__ComplexStmtEnd-1); -} -gb_inline bool is_ast_node_decl(AstNode *node) { - return gb_is_between(node->kind, AstNode__DeclBegin+1, AstNode__DeclEnd-1); -} -gb_inline bool is_ast_node_type(AstNode *node) { - return gb_is_between(node->kind, AstNode__TypeBegin+1, AstNode__TypeEnd-1); -} -gb_inline bool is_ast_node_when_stmt(AstNode *node) { - return node->kind == AstNode_WhenStmt; -} - - Token ast_node_token(AstNode *node) { switch (node->kind) { case AstNode_Ident: return node->Ident.token; @@ -3135,7 +2595,7 @@ AstNode *parse_results(AstFile *f) { AstNode *list = nullptr; expect_token(f, Token_OpenParen); - list = parse_field_list(f, nullptr, 0, Token_CloseParen, true, false); + list = parse_field_list(f, nullptr, FieldFlag_Results, Token_CloseParen, true, false); expect_token_after(f, Token_CloseParen, "parameter list"); return list; } @@ -3547,6 +3007,10 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok Array<AstNode *> names = {}; AstNode *type = list[i].node; Token token = blank_token; + if (allowed_flags&FieldFlag_Results) { + // NOTE(bill): Make this nothing and not `_` + token.string = str_lit(""); + } array_init_count(&names, heap_allocator(), 1); token.pos = ast_node_token(type).pos; @@ -3725,11 +3189,11 @@ AstNode *parse_return_stmt(AstFile *f) { while (f->curr_token.kind != Token_Semicolon) { AstNode *arg = parse_expr(f, false); - if (f->curr_token.kind == Token_Eq) { - Token eq = expect_token(f, Token_Eq); - AstNode *value = parse_value(f); - arg = ast_field_value(f, arg, value, eq); - } + // if (f->curr_token.kind == Token_Eq) { + // Token eq = expect_token(f, Token_Eq); + // AstNode *value = parse_value(f); + // arg = ast_field_value(f, arg, value, eq); + // } array_add(&results, arg); if (f->curr_token.kind != Token_Comma || |