Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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['\"'] = '\"';
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
            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);
            }
Ejemplo n.º 5
0
        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;
        }
Ejemplo n.º 6
0
        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));
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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));
        }
Ejemplo n.º 9
0
        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));
        }
Ejemplo n.º 10
0
        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));
        }
Ejemplo n.º 11
0
        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,
                });
            }
        }
Ejemplo n.º 12
0
        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
            });
        }
Ejemplo n.º 13
0
        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));
        }