added return statement
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
if false
|
if true
|
||||||
{
|
{
|
||||||
3;
|
return 3;
|
||||||
2;
|
2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
4;
|
4;
|
||||||
99;
|
return 99;
|
||||||
@@ -8,6 +8,7 @@ typedef enum {
|
|||||||
NODE_EXPR,
|
NODE_EXPR,
|
||||||
NODE_IFELSE,
|
NODE_IFELSE,
|
||||||
NODE_COMP,
|
NODE_COMP,
|
||||||
|
NODE_RETURN,
|
||||||
} NodeKind;
|
} NodeKind;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -86,4 +87,9 @@ typedef struct {
|
|||||||
Node base;
|
Node base;
|
||||||
Node *head;
|
Node *head;
|
||||||
} CompoundNode;
|
} CompoundNode;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Node base;
|
||||||
|
Node *val;
|
||||||
|
} ReturnNode;
|
||||||
#endif
|
#endif
|
||||||
@@ -205,6 +205,19 @@ static _Bool emit_instr_for_node(ExeBuilder *exeb, Node *node, Error *error)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case NODE_RETURN:
|
||||||
|
{
|
||||||
|
ReturnNode *ret = (ReturnNode*) node;
|
||||||
|
|
||||||
|
if(!emit_instr_for_node(exeb, ret->val, error))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!ExeBuilder_Append(exeb, error, OPCODE_RETURN, NULL, 0, ret->base.offset, ret->base.length))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ typedef enum {
|
|||||||
TKWNONE,
|
TKWNONE,
|
||||||
TKWTRUE,
|
TKWTRUE,
|
||||||
TKWFALSE,
|
TKWFALSE,
|
||||||
|
TKWRETURN,
|
||||||
} TokenKind;
|
} TokenKind;
|
||||||
|
|
||||||
typedef struct Token Token;
|
typedef struct Token Token;
|
||||||
@@ -140,6 +141,10 @@ AST *parse(Source *src, BPAlloc *alloc, Error *error)
|
|||||||
{
|
{
|
||||||
tok->kind = TKWFALSE;
|
tok->kind = TKWFALSE;
|
||||||
}
|
}
|
||||||
|
else if(matchstr(str + tok->offset, tok->length, "return"))
|
||||||
|
{
|
||||||
|
tok->kind = TKWRETURN;
|
||||||
|
}
|
||||||
|
|
||||||
#undef matchstr
|
#undef matchstr
|
||||||
}
|
}
|
||||||
@@ -366,6 +371,32 @@ static Node *parse_statement(Context *ctx)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TKWRETURN:
|
||||||
|
{
|
||||||
|
int offset = current_token(ctx)->offset;
|
||||||
|
|
||||||
|
next(ctx); // Consume the "return" keyword.
|
||||||
|
|
||||||
|
Node *val = parse_expression_statement(ctx);
|
||||||
|
|
||||||
|
if(val == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ReturnNode *node = BPAlloc_Malloc(ctx->alloc, sizeof(ReturnNode));
|
||||||
|
|
||||||
|
if(node == NULL)
|
||||||
|
{
|
||||||
|
Error_Report(ctx->error, 1, "No memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->base.kind = NODE_RETURN;
|
||||||
|
node->base.next = NULL;
|
||||||
|
node->base.offset = offset;
|
||||||
|
node->base.length = val->offset + val->length - offset;
|
||||||
|
node->val = val;
|
||||||
|
return (Node*) node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error_Report(ctx->error, 0, "Got token \"%.*s\" where the start of a statement was expected",
|
Error_Report(ctx->error, 0, "Got token \"%.*s\" where the start of a statement was expected",
|
||||||
|
|||||||
+53
@@ -328,7 +328,60 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
case DISASSEMBLY:
|
case DISASSEMBLY:
|
||||||
{
|
{
|
||||||
|
// Load
|
||||||
|
Source *src;
|
||||||
|
{
|
||||||
|
if(opts.input_is_file)
|
||||||
|
src = Source_FromFile(opts.input, &error);
|
||||||
|
else
|
||||||
|
src = Source_FromString(NULL, opts.input, -1, &error);
|
||||||
|
|
||||||
|
if(src == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "FATAL: %s.\n", error.message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile
|
||||||
|
Executable *exe;
|
||||||
|
{
|
||||||
|
BPAlloc *alloc = BPAlloc_Init(-1);
|
||||||
|
|
||||||
|
if(alloc == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
AST *ast = parse(src, alloc, &error);
|
||||||
|
|
||||||
|
if(ast == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "PARSING ERROR: %s.\n", error.message);
|
||||||
|
|
||||||
|
Error_Free(&error);
|
||||||
|
BPAlloc_Free(alloc);
|
||||||
|
Source_Free(src);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
exe = compile(ast, alloc, &error);
|
||||||
|
|
||||||
|
if(exe == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "COMPILATION ERROR: %s.\n", error.message);
|
||||||
|
|
||||||
|
Error_Free(&error);
|
||||||
|
BPAlloc_Free(alloc);
|
||||||
|
Source_Free(src);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPAlloc_Free(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
Executable_Dump(exe);
|
Executable_Dump(exe);
|
||||||
|
|
||||||
|
Executable_Free(exe);
|
||||||
|
Source_Free(src);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user