Typespec *parse_type_base() { var buf = PtrBuffer.Create(); var pos = token.pos; if (is_token(TOKEN_NAME)) { buf->Add(token.name); next_token(); while (match_token(TOKEN_DOT)) { buf->Add(parse_name()); } return(new_typespec_name(pos, (char **)buf->_begin, buf->count)); } if (match_keyword(func_keyword)) { return(parse_type_func()); } if (match_token(TOKEN_LPAREN)) { var type = parse_type(); expect_token(TOKEN_RPAREN); return(type); } if (match_token(TOKEN_LBRACE)) { return(parse_type_tuple()); } fatal_error_here("Unexpected token {0} in type", token_info()); return(null); }
public void lex_init() { if (inited) { return; } keywords = PtrBuffer.Create(); assign_token_to_binary_token[(int)TOKEN_ADD_ASSIGN] = TOKEN_ADD; assign_token_to_binary_token[(int)TOKEN_SUB_ASSIGN] = TOKEN_SUB; assign_token_to_binary_token[(int)TOKEN_OR_ASSIGN] = TOKEN_OR; assign_token_to_binary_token[(int)TOKEN_AND_ASSIGN] = TOKEN_AND; assign_token_to_binary_token[(int)TOKEN_XOR_ASSIGN] = TOKEN_XOR; assign_token_to_binary_token[(int)TOKEN_LSHIFT_ASSIGN] = TOKEN_LSHIFT; assign_token_to_binary_token[(int)TOKEN_RSHIFT_ASSIGN] = TOKEN_RSHIFT; assign_token_to_binary_token[(int)TOKEN_MUL_ASSIGN] = TOKEN_MUL; assign_token_to_binary_token[(int)TOKEN_DIV_ASSIGN] = TOKEN_DIV; assign_token_to_binary_token[(int)TOKEN_MOD_ASSIGN] = TOKEN_MOD; init_tokens(); init_keywords(); char_to_digit['0'] = 0; char_to_digit['1'] = 1; char_to_digit['2'] = 2; char_to_digit['3'] = 3; char_to_digit['4'] = 4; char_to_digit['5'] = 5; char_to_digit['6'] = 6; char_to_digit['7'] = 7; char_to_digit['8'] = 8; char_to_digit['9'] = 9; char_to_digit['a'] = 10; char_to_digit['b'] = 11; char_to_digit['c'] = 12; char_to_digit['d'] = 13; char_to_digit['e'] = 14; char_to_digit['f'] = 15; char_to_digit['A'] = 10; char_to_digit['B'] = 11; char_to_digit['C'] = 12; char_to_digit['D'] = 13; char_to_digit['E'] = 14; char_to_digit['F'] = 15; escape_to_char['n'] = '\n'; escape_to_char['r'] = '\r'; escape_to_char['t'] = '\t'; escape_to_char['v'] = '\v'; escape_to_char['b'] = '\b'; escape_to_char['a'] = '\a'; escape_to_char['0'] = '\0'; escape_to_char['\\'] = '\\'; escape_to_char['\''] = '\''; escape_to_char['\"'] = '\"'; }
internal Decls *parse_decls() { var buf = PtrBuffer.Create(); while (!is_token(TOKEN_EOF)) { buf->Add(parse_decl()); } return(new_decls((Decl **)buf->_begin, buf->count)); }
public static MemArena Create() { var arena = new MemArena(); arena.arenas = PtrBuffer.Create(); arena.ptr = (byte *)Marshal.AllocHGlobal(ARENA_BLOCK_SIZE); assert(arena.ptr == ALIGN_DOWN_PTR(arena.ptr, ARENA_ALIGNMENT)); arena.end = arena.ptr + ARENA_BLOCK_SIZE; arena.arenas->Add(arena.ptr); return(arena); }
void initialise() { //local_syms = Buffer<Sym>.Create(MAX_LOCAL_SYMS); local_syms = (Sym *)xmalloc(sizeof(Sym) * MAX_LOCAL_SYMS); local_syms_end = local_syms; reachable_syms = PtrBuffer.Create(); package_list = PtrBuffer.Create(); sorted_syms = PtrBuffer.Create(capacity: 256); init_compiler(); init_chars(); inited = true; }
StmtList parse_stmt_block() { expect_token(TOKEN_LBRACE); var pos = token.pos; var buf = PtrBuffer.Create(); while (!is_token_eof() && !is_token(TOKEN_RBRACE)) { buf->Add(parse_stmt()); } expect_token(TOKEN_RBRACE); return(stmt_list(pos, (Stmt **)buf->_begin, buf->count)); }
Expr *parse_expr_base() { var pos = token.pos; var expr = parse_expr_operand(); while (is_token(TOKEN_LPAREN) || is_token(TOKEN_LBRACKET) || is_token(TOKEN_DOT) || is_token(TOKEN_INC) || is_token(TOKEN_DEC)) { if (match_token(TOKEN_LPAREN)) { var buf = PtrBuffer.Create(); if (!is_token(TOKEN_RPAREN)) { buf->Add(parse_expr()); while (match_token(TOKEN_COMMA)) { buf->Add(parse_expr()); } } expect_token(TOKEN_RPAREN); expr = new_expr_call(pos, expr, (Expr **)buf->_begin, buf->count); } else if (match_token(TOKEN_LBRACKET)) { var index = parse_expr(); expect_token(TOKEN_RBRACKET); expr = new_expr_index(pos, expr, index); } else if (is_token(TOKEN_DOT)) { next_token(); var field = token.name; expect_token(TOKEN_NAME); expr = new_expr_field(pos, expr, field); } else { assert(is_token(TOKEN_INC) || is_token(TOKEN_DEC)); TokenKind op = token.kind; next_token(); expr = new_expr_modify(pos, op, true, expr); } } return(expr); }
Typespec *parse_type_tuple() { SrcPos pos = token.pos; PtrBuffer *fields = PtrBuffer.Create(); while (!is_token(TOKEN_RBRACE)) { Typespec *field = parse_type(); fields->Add(field); if (!match_token(TOKEN_COMMA)) { break; } } expect_token(TOKEN_RBRACE); return(new_typespec_tuple(pos, (Typespec **)fields->_begin, fields->count)); }
Stmt *parse_stmt_if(SrcPos pos) { expect_token(TOKEN_LPAREN); Expr *cond = parse_expr(); Stmt *init = parse_init_stmt(cond); if (init != null) { if (match_token(TOKEN_SEMICOLON)) { cond = parse_expr(); } else { cond = null; } } expect_token(TOKEN_RPAREN); var then_block = parse_stmt_block(); var else_block = default(StmtList); var buf = PtrBuffer.Create(); while (match_keyword(else_keyword)) { if (!match_keyword(if_keyword)) { else_block = parse_stmt_block(); break; } var elseif_cond = parse_paren_expr(); var elseif_block = parse_stmt_block(); var elif = (ElseIf *)xmalloc(sizeof(ElseIf)); elif->cond = elseif_cond; elif->block = elseif_block; buf->Add(elif); } return(new_stmt_if(pos, init, cond, then_block, (ElseIf **)buf->_begin, buf->count, else_block)); }
Typespec *parse_type_func() { var buf = PtrBuffer.Create(); var pos = token.pos; bool has_varargs = false; expect_token(TOKEN_LPAREN); if (!is_token(TOKEN_RPAREN)) { buf->Add(parse_type_func_param()); while (match_token(TOKEN_COMMA)) { if (match_token(TOKEN_ELLIPSIS)) { if (has_varargs) { error_here("Multiple ellipsis instances in function type"); } has_varargs = true; } else { if (has_varargs) { error_here("Ellipsis must be last parameter in function type"); } buf->Add(parse_type_func_param()); } } } expect_token(TOKEN_RPAREN); Typespec *ret = null; if (match_token(TOKEN_COLON)) { ret = parse_type(); } return(new_typespec_func(pos, (Typespec **)buf->_begin, buf->count, ret, has_varargs)); }
AggregateItem parse_decl_aggregate_item() { var pos = token.pos; if (match_keyword(struct_keyword)) { return(new AggregateItem { pos = pos, kind = AGGREGATE_ITEM_SUBAGGREGATE, subaggregate = parse_aggregate(AGGREGATE_STRUCT), }); } else if (match_keyword(union_keyword)) { return(new AggregateItem { pos = pos, kind = AGGREGATE_ITEM_SUBAGGREGATE, subaggregate = parse_aggregate(AGGREGATE_UNION), }); } else { var names = PtrBuffer.Create(); names->Add(parse_name()); while (match_token(TOKEN_COMMA)) { names->Add(parse_name()); } expect_token(TOKEN_COLON); Typespec *type = parse_type(); expect_token(TOKEN_SEMICOLON); return(new AggregateItem { pos = pos, kind = AGGREGATE_ITEM_FIELD, names = (char **)names->_begin, num_names = names->count, type = type, }); } }
SwitchCase parse_stmt_switch_case() { var patterns = Buffer <SwitchCasePattern> .Create(); var is_default = false; var is_first_case = true; while (is_keyword(case_keyword) || is_keyword(default_keyword)) { if (match_keyword(case_keyword)) { if (!is_first_case) { warning_here("Use comma-separated expressions to match multiple values with one case label"); is_first_case = false; } patterns.Add(parse_switch_case_pattern()); while (match_token(TOKEN_COMMA)) { patterns.Add(parse_switch_case_pattern()); } } else { assert(is_keyword(default_keyword)); next_token(); if (is_default) { error_here("Duplicate default labels in same switch clause"); } is_default = true; } expect_token(TOKEN_COLON); } var pos = token.pos; var buf = PtrBuffer.Create(); while (!is_token_eof() && !is_token(TOKEN_RBRACE) && !is_keyword(case_keyword) && !is_keyword(default_keyword)) { buf->Add(parse_stmt()); } var block = new StmtList { pos = pos, stmts = (Stmt **)buf->_begin, num_stmts = buf->count }; return(new SwitchCase { patterns = patterns, num_patterns = patterns.count, is_default = is_default, block = block }); }
Decl *parse_decl_import(SrcPos pos) { char *rename_name = null; repeat: bool is_relative = match_token(TOKEN_DOT); char *name = token.name; expect_token(TOKEN_NAME); if (!is_relative && match_token(TOKEN_ASSIGN)) { if (rename_name != null) { fatal_error(pos, "Only one import assignment is allowed"); } rename_name = name; goto repeat; } var names = PtrBuffer.Create(); names->Add(name); while (match_token(TOKEN_DOT)) { names->Add(parse_name()); } bool import_all = false; var items = Buffer <ImportItem> .Create(); if (match_token(TOKEN_LBRACE)) { while (!is_token(TOKEN_RBRACE)) { if (match_token(TOKEN_ELLIPSIS)) { import_all = true; } else { char *name2 = parse_name(); if (match_token(TOKEN_ASSIGN)) { items.Add(new ImportItem { name = parse_name(), rename = name2 }); } else { items.Add(new ImportItem { name = name2 }); } if (!match_token(TOKEN_COMMA)) { break; } } } expect_token(TOKEN_RBRACE); } return(new_decl_import(pos, rename_name, is_relative, (char **)names->_begin, names->count, import_all, items, items.count)); }