1
0
Fork 0
mirror of https://github.com/pnx/m16vm synced 2026-06-16 03:44:55 +02:00

src/as/parser.c: do semantics checks.

This commit is contained in:
Henrik Hautakoski 2018-12-10 22:55:20 +01:00
parent aa171ac46c
commit 0916f8bcdc
No known key found for this signature in database
GPG key ID: 839F3A7EAFAEAFAA

View file

@ -175,6 +175,29 @@ static int parse_line(struct lexer* lex, struct ast *ast) {
return 0;
}
// Check the semantics of the program's AST.
// For now, we only need to check that all
// referenced labels exist in the symbol table
static int check_semantics(struct ast* ast) {
int i;
// TODO: Need to implement a iterator for vectors.
for(i = 0; i < ast->instr.size; i += sizeof(struct ast_instr)) {
struct ast_instr *instr = ast->instr.base + i;
// Only J-Type can have labels.
if (instr->opcode == OP_JMP
&& instr->operands[0].type == DATATYPE_STRING
&& symtab_get(ast->symbols, instr->operands[0].s, NULL) < 0) {
return asm_error(0, "Label '%s' is not defined", instr->operands[0].s);
}
}
return 0;
}
/*
* Main parser function.
*/
@ -192,8 +215,8 @@ int parse(FILE *source_fd, FILE *dest_fd) {
rc = parse_line(&lex, &ast);
} while(rc >= 0);
// TODO: Second pass validation
// make sure all referenced labels are actually defined.
if (check_semantics(&ast) < 0)
goto done;
// Code generation
for(int i = 0; i < ast.instr.size; i += sizeof(struct ast_instr)) {
@ -206,7 +229,6 @@ int parse(FILE *source_fd, FILE *dest_fd) {
}
// Cleanup
ast_free(&ast);
done: ast_free(&ast);
return 0;
}