aboutsummaryrefslogtreecommitdiff
path: root/src/as_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/as_parser.c')
-rw-r--r--src/as_parser.c132
1 files changed, 42 insertions, 90 deletions
diff --git a/src/as_parser.c b/src/as_parser.c
index 0fcb1f4..a68fbba 100644
--- a/src/as_parser.c
+++ b/src/as_parser.c
@@ -17,37 +17,28 @@
// <op> ::= "add" | "sub" | "mul" | "div" | "mod" | "eq" | ...
struct result parse_prog(struct allocator * alct, struct token_stream * ts) {
- struct result result;
struct prog * p = allocate(alct, sizeof(struct prog));
- result = parse_stmts(alct, ts);
- if (result.errmsg != NULL) return result;
- p->stmts = result.value;
- return (struct result){.value = p, .errmsg = NULL};
+ p->stmts = unwrap(parse_stmts(alct, ts));
+ return ok(p);
}
struct result parse_stmts(struct allocator * alct, struct token_stream * ts) {
struct token *token;
- struct result result;
- const char* errmsg;
struct stmts * ss = allocate(alct, sizeof(struct stmts));
+ struct stmt * s;
+
ss->stmts = allocate(alct, sizeof(struct stmt *));
ss->stmts[0] = NULL;
int capacity = 0;
int len = 0;
while (1) {
- result = peek_token(alct, ts);
- if (result.errmsg != NULL) return result;
- token = result.value;
+ token = unwrap(peek_token(alct, ts));
if (token->type == TK_ENDOFFILE) {
break;
}
-
- result = parse_stmt(alct, ts);
- if (result.errmsg != NULL) {
- return result;
- }
- struct stmt * s = result.value;
+
+ s = unwrap(parse_stmt(alct, ts));
if (s == NULL) continue;
if (len == capacity) {
size_t new_capacity = capacity * 2 + 1;
@@ -57,136 +48,97 @@ struct result parse_stmts(struct allocator * alct, struct token_stream * ts) {
capacity = new_capacity;
}
// expect newline
- result = peek_token(alct, ts);
- if (result.errmsg != NULL) return result;
- token = result.value;
+ token = unwrap(peek_token(alct, ts));
if (token->type == TK_NEWLINE) {
- result = next_token(alct, ts);
- if (result.errmsg != NULL) return result;
+ unwrap(next_token(alct, ts));
} else {
- errmsg = safe_sprintf(alct, "%d:%d expect newline.\n", token->line, token->col);
- return (struct result){.value = NULL, .errmsg = errmsg};
+ return err(safe_sprintf(alct, "%d:%d expect newline.\n", token->line, token->col));
}
ss->stmts[len] = s;
len++;
}
ss->stmts[len] = NULL;
- return (struct result){.value = ss, .errmsg = NULL};
+ return ok(ss);
}
struct result parse_label(struct allocator * alct, struct token_stream * ts) {
- const char *errmsg;
- struct result result;
struct token * t;
- result = next_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
+ t = unwrap(next_token(alct, ts));
if (t->type != TK_TAG) {
- errmsg = safe_sprintf(alct, "%d:%d expect label.\n", t->line, t->col);
- return (struct result){.value = NULL, .errmsg = errmsg};
+ return err(safe_sprintf(alct, "%d:%d expect label.\n", t->line, t->col));
}
struct label * l = allocate(alct, sizeof(struct label *));
l->name = t->sval;
- result = next_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
+ t = unwrap(next_token(alct, ts));
if (t->type != TK_COLON) {
- errmsg = safe_sprintf(alct, "%d:%d expect colon.\n", t->line, t->col);
- return (struct result){.value = NULL, .errmsg = errmsg};
+ return err(safe_sprintf(alct, "%d:%d expect colon.\n", t->line, t->col));
}
- return (struct result){.value = l, .errmsg = NULL};
+ return ok(l);
}
struct result parse_stmt(struct allocator * alct, struct token_stream * ts) {
const char *errmsg;
- struct result result;
- struct token * t;
- result = peek_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
+ struct token * token;
+ token = unwrap(peek_token(alct, ts));
struct stmt * stmt = allocate(alct, sizeof(struct stmt));
stmt->label = NULL;
stmt->instr = NULL;
- if (t->type == TK_TAG) {
- result = parse_label(alct, ts);
- if (result.errmsg != NULL) return result;
- stmt->label = result.value;
- result = peek_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
- if (t->type == TK_NEWLINE) {
- return (struct result){.value = stmt, .errmsg = NULL};
+ if (token->type == TK_TAG) {
+ stmt->label = unwrap(parse_label(alct, ts));
+ token = unwrap(peek_token(alct, ts));
+ if (token->type == TK_NEWLINE) {
+ return ok(stmt);
}
- result = peek_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
+ token = unwrap(peek_token(alct, ts));
}
- if (t->type == TK_OP) {
- result = parse_instr(alct, ts);
- if (result.errmsg != NULL) return result;
- stmt->instr = result.value;
-
- result = peek_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
- if (t->type == TK_NEWLINE) {
- return (struct result){.value = stmt, .errmsg = NULL};
+ if (token->type == TK_OP) {
+ stmt->instr = unwrap(parse_instr(alct, ts));
+ token = unwrap(peek_token(alct, ts));
+ if (token->type == TK_NEWLINE) {
+ return ok(stmt);
}
}
- if (t->type == TK_NEWLINE) {
- return (struct result){.value = NULL, .errmsg = NULL};
+ if (token->type == TK_NEWLINE) {
+ return ok(NULL);
}
- errmsg = safe_sprintf(alct, "%d:%d expect lable + instruction, lable, or instruction.\n", t->line, t->col);
- return (struct result){.value = NULL, .errmsg = errmsg};
+ return err(safe_sprintf(alct, "%d:%d expect lable + instruction, lable, or instruction.\n", token->line, token->col));
}
struct result parse_op(struct allocator * alct, struct token_stream * ts) {
- const char *errmsg;
- struct result result;
struct token * t;
- result = next_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
+ t = unwrap(next_token(alct, ts));
enum op op;
if (t->type == TK_OP) {
op = str2op(t->sval);
if (op == OP_END) {
- errmsg = safe_sprintf(alct, "%d:%d invalid op.\n", t->line, t->col);
- return (struct result){.value = NULL, .errmsg = errmsg};
+ return err(safe_sprintf(alct, "%d:%d invalid op.\n", t->line, t->col));
}
} else {
- errmsg = safe_sprintf(alct, "%d:%d expect op.\n", t->line, t->col);
- return (struct result){.value = NULL, .errmsg = errmsg};
+ return err(safe_sprintf(alct, "%d:%d expect op.\n", t->line, t->col));
}
- return (struct result){.value = (void*)op, .errmsg = NULL};
+ return ok((void*)op);
}
struct result parse_instr(struct allocator * alct, struct token_stream * ts) {
- struct result result;
struct token * t;
- result = peek_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
+ t = unwrap(peek_token(alct, ts));
struct instr * i = allocate(alct, sizeof(struct instr));
i->tag_name = NULL;
i->arg = NULL;
i->op = OP_END;
if (t->type == TK_OP) {
- result = parse_op(alct, ts);
- i->op = (enum op)(result.value);
- result = peek_token(alct, ts);
- if (result.errmsg != NULL) return result;
- t = result.value;
+ i->op = (enum op)unwrap(parse_op(alct, ts));
+ t = unwrap(peek_token(alct, ts));
if (t->type == TK_ARG) {
struct arg * a = allocate(alct, sizeof(struct arg));
a->ival = t->ival;
a->fval = t->fval;
i->arg = a;
- next_token(alct, ts);
+ unwrap(next_token(alct, ts));
} else if (t->type == TK_TAG) {
i->tag_name = t->sval;
- next_token(alct, ts);
+ unwrap(next_token(alct, ts));
}
}
- return (struct result){.value = i, .errmsg = NULL};
+ return ok(i);
}