diff options
Diffstat (limited to 'src/as_parser.c')
| -rw-r--r-- | src/as_parser.c | 132 |
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); } |
