CT for now parses properly.

This commit is contained in:
Christoffer Lerno
2019-09-13 00:38:52 +02:00
parent b7c64a46ea
commit f6c07d86d0
9 changed files with 96 additions and 37 deletions

View File

@@ -23,9 +23,7 @@ There are some small work being done on the parser here, but most of the structu
#### What's missing in the parser
- `asm` sections.
- `$each` compile time statement.
- Macro parameter lists to imports.
- extending `generics` declaration.
- auxiliary data for enums.
#### What's missing in the semantic analyser
@@ -37,7 +35,7 @@ There are some small work being done on the parser here, but most of the structu
- `catch`, `throws` and `try` statements.
- `generic` not analysed.
- `attribute` not analysed.
- `$switch` and `$each` not handled.
- `$switch` and `$for` not handled.
- Enums not correctly handled.
- Errors not correctly handles.
- Type resolution not complete for all types.

View File

@@ -62,7 +62,15 @@ void comment(void);
"throws" { count(); return(THROWS); }
"func" { count(); return(FUNC); }
"nil" { count(); return(NIL); }
"next" { count(); return(NEXT);
"next" { count(); return(NEXT); }
"in" { count(); return(IN); }
"$for" { count(); return(CTFOR); }
"$case" { count(); return(CTCASE); }
"$switch" { count(); return(CTSWITCH); }
"$default" { count(); return(CTDEFAULT); }
"$if" { count(); return(CTIF); }
"$elif" { count(); return(CTELIF); }
"$else" { count(); return(CTELSE); }
[_]*[A-Z]{UA}* { count(); return(CONST_IDENT); }
[_]*[A-Z]{UA}*[a-z]{AN}* { count(); return(TYPE_IDENT); }

View File

@@ -21,8 +21,8 @@ void yyerror(char *s);
%token STRUCT UNION ENUM ELLIPSIS AS LOCAL
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
%token TYPE FUNC ERROR MACRO GENERIC CTIF CTELIF CTENDIF CTELSE CTSWITCH CTCASE CTDEFAULT CTEACH
%token THROWS THROW TRY CATCH SCOPE PUBLIC DEFER ATTRIBUTE
%token TYPE FUNC ERROR MACRO GENERIC CTIF CTELIF CTENDIF CTELSE CTSWITCH CTCASE CTDEFAULT CTFOR
%token THROWS THROW TRY CATCH SCOPE PUBLIC DEFER ATTRIBUTE IN
%start translation_unit
%%
@@ -32,6 +32,7 @@ path
| path IDENT SCOPE
;
ident_expression
: CONST_IDENT
| IDENT
@@ -298,11 +299,16 @@ ct_switch_body
| ct_switch_body ct_case_statement
;
ct_for_stmt
: CTFOR '(' CT_IDENT IN expression ')' statement
| CTFOR '(' CT_IDENT ',' CT_IDENT IN expression ')' statement
;
ct_statement
: ct_if compound_statement
| ct_if compound_statement ct_else_body
| ct_switch '{' ct_switch_body '}'
| CTEACH '(' expression AS CT_IDENT ')' statement
| ct_for_stmt
;
throw_statement

View File

@@ -583,6 +583,18 @@ static void fprint_ast_recursive(FILE *file, Ast *ast, int indent)
fprint_ast_recursive(file, ast->while_stmt.cond, indent + 1);
fprint_ast_recursive(file, ast->while_stmt.body, indent + 1);
break;
case AST_CT_FOR_STMT:
if (ast->ct_for_stmt.index.string)
{
fprintf(file, "($for %s, %s\n", ast->ct_for_stmt.index.string, ast->ct_for_stmt.value.string);
}
else
{
fprintf(file, "($for %s\n", ast->ct_for_stmt.value.string);
}
fprint_expr_recursive(file, ast->ct_for_stmt.expr, indent + 1);
fprint_ast_recursive(file, ast->ct_for_stmt.body, indent + 1);
break;
case AST_DO_STMT:
fprintf(file, "(do\n");
fprint_ast_recursive(file, ast->do_stmt.body, indent + 1);

View File

@@ -680,8 +680,6 @@ static void codegen_ast(Context *context, Ast *ast, int indent)
UNREACHABLE
case AST_ASM_STMT:
break;
case AST_ATTRIBUTE:
break;
case AST_BREAK_STMT:
codegen_emit_break_stmt(context, ast, indent);
return;
@@ -696,12 +694,6 @@ static void codegen_ast(Context *context, Ast *ast, int indent)
break;
case AST_CONTINUE_STMT:
break;
case AST_CT_IF_STMT:
break;
case AST_CT_ELIF_STMT:
break;
case AST_CT_ELSE_STMT:
break;
case AST_DECLARE_STMT:
codegen_declare_stmt(context, ast, indent);
return;
@@ -756,21 +748,21 @@ static void codegen_ast(Context *context, Ast *ast, int indent)
return;
case AST_VOLATILE_STMT:
break;
case AST_WHILE_STMT:
UNREACHABLE
case AST_GENERIC_CASE_STMT:
break;
case AST_GENERIC_DEFAULT_STMT:
break;
case AST_STMT_LIST:
codegen_emit_stmt_list(context, ast, indent);
return;
case AST_CT_SWITCH_STMT:
break;
case AST_CT_DEFAULT_STMT:
break;
case AST_CT_IF_STMT:
case AST_CT_ELIF_STMT:
case AST_CT_ELSE_STMT:
case AST_CT_CASE_STMT:
break;
case AST_ATTRIBUTE:
case AST_CT_FOR_STMT:
case AST_GENERIC_CASE_STMT:
case AST_GENERIC_DEFAULT_STMT:
case AST_WHILE_STMT:
UNREACHABLE
}
TODO
}

View File

@@ -229,6 +229,7 @@ typedef struct
struct _Ast **cases;
Token *parameters;
Type *rtype; // May be null!
Path *path; // For redefinition
} GenericDecl;
@@ -543,6 +544,14 @@ typedef struct
Ast *body;
} AstCtCaseStmt;
typedef struct
{
Token index;
Token value;
Expr *expr;
Ast *body;
} AstCtForStmt;
typedef struct _Ast
{
AstKind ast_kind : 8;
@@ -577,6 +586,7 @@ typedef struct _Ast
AstCtIfStmt ct_if_stmt;
AstCtIfStmt ct_elif_stmt;
Ast *ct_else_stmt;
AstCtForStmt ct_for_stmt;
AstGenericCaseStmt generic_case_stmt;
Ast *generic_default_stmt;
Ast** stmt_list;

View File

@@ -36,6 +36,7 @@ typedef enum
AST_CT_IF_STMT,
AST_CT_ELIF_STMT,
AST_CT_ELSE_STMT,
AST_CT_FOR_STMT,
AST_CT_SWITCH_STMT,
AST_CT_DEFAULT_STMT,
AST_CT_CASE_STMT,
@@ -395,6 +396,7 @@ typedef enum
TOKEN_GOTO,
TOKEN_IF,
TOKEN_IMPORT,
TOKEN_IN,
TOKEN_LOCAL,
TOKEN_MACRO,
TOKEN_MODULE,
@@ -428,7 +430,7 @@ typedef enum
TOKEN_CT_CASE, // $case
TOKEN_CT_DEFAULT, // $default
TOKEN_CT_EACH, // $each
TOKEN_CT_FOR, // $for
TOKEN_CT_ELIF, // $elif
TOKEN_CT_ELSE, // $else
TOKEN_CT_IF, // $if

View File

@@ -1025,10 +1025,32 @@ static inline Ast* parse_ct_if_stmt(void)
}
static inline Ast* parse_ct_each_stmt(void)
/**
* ct_for_stmt
* : CTFOR '(' CT_IDENT IN expression ')' statement
* | CTFOR '(' CT_IDENT, CT_IDENT IN expression ')' statement
* ;
*
* @return
*/
static inline Ast* parse_ct_for_stmt(void)
{
TODO
Ast *ast = AST_NEW(AST_CT_FOR_STMT, tok);
advance_and_verify(TOKEN_CT_FOR);
CONSUME_OR(TOKEN_LPAREN, &poisoned_ast);
if (next_tok.type == TOKEN_COMMA)
{
ast->ct_for_stmt.index = tok;
TRY_CONSUME_OR(TOKEN_CT_IDENT, "Expected a compile time index variable", &poisoned_ast);
advance_and_verify(TOKEN_COMMA);
}
ast->ct_for_stmt.value = tok;
TRY_CONSUME_OR(TOKEN_CT_IDENT, "Expected a compile time variable", &poisoned_ast);
TRY_CONSUME_OR(TOKEN_IN, "Expected 'in'.", &poisoned_ast);
ast->ct_for_stmt.expr = TRY_EXPR_OR(parse_expr(), &poisoned_ast);
CONSUME_OR(TOKEN_RPAREN, &poisoned_ast);
ast->ct_for_stmt.body = TRY_AST(parse_stmt());
return ast;
}
@@ -1312,8 +1334,8 @@ static Ast *parse_stmt(void)
return parse_ct_if_stmt();
case TOKEN_CT_SWITCH:
return parse_ct_switch_stmt();
case TOKEN_CT_EACH:
return parse_ct_each_stmt();
case TOKEN_CT_FOR:
return parse_ct_for_stmt();
case TOKEN_THROW:
return parse_throw_stmt();
case TOKEN_VOLATILE:
@@ -1416,6 +1438,7 @@ static Ast *parse_stmt(void)
case TOKEN_CT_ELIF:
case TOKEN_CT_ELSE:
case TOKEN_CT_DEFAULT:
case TOKEN_IN:
SEMA_ERROR(tok, "Unexpected '%s' found when expecting a statement.", token_type_to_string(tok.type));
advance();
return &poisoned_ast;
@@ -1913,10 +1936,14 @@ static inline Ast *parse_generics_statements(void)
/**
* // TODO module?
* generics_declaration
* : GENERIC IDENT '(' macro_argument_list ')' '{' generics_body '}'
* | GENERIC type_expression IDENT '(' macro_argument_list ')' '{' generics_body '}'
* : GENERIC opt_path IDENT '(' macro_argument_list ')' '{' generics_body '}'
* | GENERIC type_expression opt_path IDENT '(' macro_argument_list ')' '{' generics_body '}'
* ;
*
* opt_path
* :
* | path
* ;
*
* @param visibility
@@ -1930,7 +1957,9 @@ static inline Decl *parse_generics_declaration(Visibility visibility)
{
rtype = TRY_TYPE_OR(parse_type_expression(), &poisoned_decl);
}
Path *path = parse_path();
Decl *decl = decl_new_user_defined_type(tok, DECL_GENERIC, visibility);
decl->generic_decl.path = path;
if (!consume_ident("generic function name")) return &poisoned_decl;
decl->generic_decl.rtype = rtype;
Token *parameters = NULL;

View File

@@ -191,10 +191,12 @@ const char *token_type_to_string(TokenType type)
return "generic";
case TOKEN_GOTO:
return "goto";
case TOKEN_IMPORT:
return "import";
case TOKEN_IF:
return "if";
case TOKEN_IMPORT:
return "import";
case TOKEN_IN:
return "in";
case TOKEN_LOCAL:
return "local";
case TOKEN_MACRO:
@@ -321,8 +323,8 @@ const char *token_type_to_string(TokenType type)
return "$case";
case TOKEN_CT_DEFAULT:
return "$default";
case TOKEN_CT_EACH:
return "$each";
case TOKEN_CT_FOR:
return "$for";
case TOKEN_CT_ELSE:
return "$else";
case TOKEN_CT_ELIF: