initial parse
This commit is contained in:
parent
9bf5fc06db
commit
f69fb284ec
368
ast_print.c
Normal file
368
ast_print.c
Normal file
@ -0,0 +1,368 @@
|
|||||||
|
#include "ast.h"
|
||||||
|
#include "collection.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void indent(FILE* f, int depth)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < depth; ++i) {
|
||||||
|
fprintf(f, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_stmt_block_print(FILE* f, const AstStmtBlock* node, int depth)
|
||||||
|
{
|
||||||
|
fprintf(f, "StmtBlock %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "stmts: [");
|
||||||
|
|
||||||
|
if (node->stmts_size) {
|
||||||
|
fprintf(f, "\n");
|
||||||
|
for (size_t i = 0; i < node->stmts_size; ++i) {
|
||||||
|
indent(f, depth + 2);
|
||||||
|
ast_stmt_print(f, node->stmts[i], depth + 2);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
}
|
||||||
|
indent(f, depth + 1);
|
||||||
|
}
|
||||||
|
fprintf(f, "],\n");
|
||||||
|
|
||||||
|
indent(f, depth);
|
||||||
|
fprintf(f, "}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_stmt_print(FILE* f, const AstStmt* node, int depth)
|
||||||
|
{
|
||||||
|
switch (node->ty) {
|
||||||
|
case AstStmt_Decl: {
|
||||||
|
fprintf(f, "Stmt::Decl %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "decl: ");
|
||||||
|
ast_decl_print(f, node->decl, depth + 1);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
|
||||||
|
indent(f, depth);
|
||||||
|
fprintf(f, "}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AstStmt_Expr: {
|
||||||
|
fprintf(f, "Stmt::Expr %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
indent(f, depth + 1);
|
||||||
|
|
||||||
|
fprintf(f, "expr: ");
|
||||||
|
|
||||||
|
ast_expr_print(f, node->expr, depth + 1);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
|
||||||
|
indent(f, depth);
|
||||||
|
fprintf(f, "}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spec_print(FILE* f, AstSpec spec)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
AstSpec specifier;
|
||||||
|
const char* ident;
|
||||||
|
} spec_idents[] = {
|
||||||
|
{ AstSpec_Int, "int" },
|
||||||
|
{ AstSpec_Char, "char" },
|
||||||
|
{ AstSpec_Unsigned, "unsigned" },
|
||||||
|
{ AstSpec_Static, "static" },
|
||||||
|
{ AstSpec_Const, "const" },
|
||||||
|
{ AstSpec_Inline, "inline" },
|
||||||
|
{ AstSpec_Typedef, "typedef" },
|
||||||
|
{ AstSpec_Enum, "enum" },
|
||||||
|
{ AstSpec_Struct, "struct" },
|
||||||
|
{ AstSpec_Union, "union" },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(spec_idents) / sizeof(spec_idents[0]); ++i) {
|
||||||
|
if (spec & spec_idents[i].specifier) {
|
||||||
|
if (!first)
|
||||||
|
fprintf(f, " ");
|
||||||
|
first = false;
|
||||||
|
fprintf(f, "%s", spec_idents[i].ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_decl_print(FILE* f, const AstDecl* node, int depth)
|
||||||
|
{
|
||||||
|
fprintf(f, "Decl %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "spec: [");
|
||||||
|
spec_print(f, node->spec);
|
||||||
|
fprintf(f, "],\n");
|
||||||
|
|
||||||
|
if (node->spec & AstSpec_DefTy) {
|
||||||
|
assert(node->type_ident);
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "type_ident: \"%s\",\n", node->type_ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "declars: [");
|
||||||
|
if (node->declars_size) {
|
||||||
|
fprintf(f, "\n");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < node->declars_size; ++i) {
|
||||||
|
indent(f, depth + 2);
|
||||||
|
ast_declar_print(f, node->declars[i], depth + 2);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
}
|
||||||
|
fprintf(f, "],\n");
|
||||||
|
|
||||||
|
if (node->function_body) {
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "function_body: ");
|
||||||
|
ast_stmt_block_print(f, node->function_body, depth + 1);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
indent(f, depth);
|
||||||
|
fprintf(f, "}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_declar_print(FILE* f, const AstDeclar* node, int depth)
|
||||||
|
{
|
||||||
|
switch (node->ty) {
|
||||||
|
case AstDeclar_Ident: {
|
||||||
|
fprintf(
|
||||||
|
f, "Declar::Ident %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "ident: \"%s\",\n", node->ident);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AstDeclar_Pointer: {
|
||||||
|
fprintf(
|
||||||
|
f, "Declar::Pointer %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "declar: ");
|
||||||
|
ast_declar_print(f, node->pointer.declar, depth + 1);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "spec: [");
|
||||||
|
spec_print(f, node->pointer.spec);
|
||||||
|
fprintf(f, "],\n");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AstDeclar_Array: {
|
||||||
|
fprintf(
|
||||||
|
f, "Declar::Array %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "declar: ");
|
||||||
|
ast_declar_print(f, node->array.declar, depth + 1);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "expr: ");
|
||||||
|
ast_expr_print(f, node->array.expr, depth + 1);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AstDeclar_Function: {
|
||||||
|
fprintf(
|
||||||
|
f, "Declar::Function %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "declar: ");
|
||||||
|
ast_declar_print(f, node->array.declar, depth + 1);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "params: [");
|
||||||
|
if (node->function.params_size) {
|
||||||
|
fprintf(f, "\n");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < node->function.params_size; ++i) {
|
||||||
|
indent(f, depth + 2);
|
||||||
|
ast_decl_print(f, node->function.params[i], depth + 2);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "],\n");
|
||||||
|
} else {
|
||||||
|
fprintf(f, "],\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->init_expr) {
|
||||||
|
indent(f, depth + 2);
|
||||||
|
fprintf(f, "decl: ");
|
||||||
|
ast_expr_print(f, node->init_expr, depth + 2);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
indent(f, depth);
|
||||||
|
fprintf(f, "}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_expr_print(FILE* f, const AstExpr* node, int depth)
|
||||||
|
{
|
||||||
|
switch (node->ty) {
|
||||||
|
case AstExpr_Ident: {
|
||||||
|
fprintf(f, "Expr::Ident %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "ident: \"%s\",\n", node->ident);
|
||||||
|
|
||||||
|
indent(f, depth);
|
||||||
|
fprintf(f, "}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AstExpr_Str: {
|
||||||
|
fprintf(f, "Expr::Str %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "str_val: \"%s\",\n", node->str_val);
|
||||||
|
|
||||||
|
indent(f, depth);
|
||||||
|
fprintf(f, "}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AstExpr_Call: {
|
||||||
|
fprintf(f, "Expr::Call %d:%d {\n", node->loc.line, node->loc.col);
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "expr: ");
|
||||||
|
ast_expr_print(f, node->call.expr, depth + 1);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
|
||||||
|
indent(f, depth + 1);
|
||||||
|
fprintf(f, "args: [");
|
||||||
|
|
||||||
|
if (node->call.args_size) {
|
||||||
|
fprintf(f, "\n");
|
||||||
|
for (size_t i = 0; i < node->call.args_size; ++i) {
|
||||||
|
indent(f, depth + 2);
|
||||||
|
ast_expr_print(f, node->call.args[i], depth + 2);
|
||||||
|
fprintf(f, ",\n");
|
||||||
|
}
|
||||||
|
indent(f, depth + 1);
|
||||||
|
}
|
||||||
|
fprintf(f, ",]\n");
|
||||||
|
|
||||||
|
indent(f, depth);
|
||||||
|
fprintf(f, "}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_stmt_block_visit(AstVisitor* v, AstStmtBlock* node)
|
||||||
|
{
|
||||||
|
if (v->visit_stmt_block && v->visit_stmt_block(v, node) == AstVisitor_Break)
|
||||||
|
return;
|
||||||
|
ast_stmt_block_visit_body(v, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_stmt_block_visit_body(AstVisitor* v, AstStmtBlock* node)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < node->stmts_size; ++i) {
|
||||||
|
ast_stmt_visit(v, node->stmts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_stmt_visit(AstVisitor* v, AstStmt* node)
|
||||||
|
{
|
||||||
|
if (v->visit_stmt && v->visit_stmt(v, node) == AstVisitor_Break)
|
||||||
|
return;
|
||||||
|
ast_stmt_visit_body(v, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_stmt_visit_body(AstVisitor* v, AstStmt* node)
|
||||||
|
{
|
||||||
|
switch (node->ty) {
|
||||||
|
case AstStmt_Decl:
|
||||||
|
ast_decl_visit(v, node->decl);
|
||||||
|
break;
|
||||||
|
case AstStmt_Expr:
|
||||||
|
ast_expr_visit(v, node->expr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_decl_visit(AstVisitor* v, AstDecl* node)
|
||||||
|
{
|
||||||
|
if (v->visit_decl && v->visit_decl(v, node) == AstVisitor_Break)
|
||||||
|
return;
|
||||||
|
ast_decl_visit_body(v, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_decl_visit_body(AstVisitor* v, AstDecl* node)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < node->declars_size; ++i)
|
||||||
|
ast_declar_visit(v, node->declars[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_declar_visit(AstVisitor* v, AstDeclar* node)
|
||||||
|
{
|
||||||
|
if (v->visit_declar && v->visit_declar(v, node) == AstVisitor_Break)
|
||||||
|
return;
|
||||||
|
ast_declar_visit_body(v, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_declar_visit_body(AstVisitor* v, AstDeclar* node)
|
||||||
|
{
|
||||||
|
switch (node->ty) {
|
||||||
|
case AstDeclar_Ident:
|
||||||
|
break;
|
||||||
|
case AstDeclar_Pointer:
|
||||||
|
ast_declar_visit(v, node->pointer.declar);
|
||||||
|
break;
|
||||||
|
case AstDeclar_Array:
|
||||||
|
ast_declar_visit(v, node->array.declar);
|
||||||
|
ast_expr_visit(v, node->array.expr);
|
||||||
|
break;
|
||||||
|
case AstDeclar_Function:
|
||||||
|
ast_declar_visit(v, node->pointer.declar);
|
||||||
|
for (size_t i = 0; i < node->function.params_size; ++i)
|
||||||
|
ast_decl_visit(v, node->function.params[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_expr_visit(AstVisitor* v, AstExpr* node)
|
||||||
|
{
|
||||||
|
if (v->visit_expr && v->visit_expr(v, node) == AstVisitor_Break)
|
||||||
|
return;
|
||||||
|
ast_expr_visit_body(v, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_expr_visit_body(AstVisitor* v, AstExpr* node)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (node->ty) {
|
||||||
|
case AstExpr_Ident:
|
||||||
|
break;
|
||||||
|
case AstExpr_Str:
|
||||||
|
break;
|
||||||
|
case AstExpr_Call:
|
||||||
|
ast_expr_visit(v, node->call.expr);
|
||||||
|
for (size_t i = 0; i < node->call.args_size; ++i)
|
||||||
|
ast_expr_visit(v, node->call.args[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
93
resolve.c
Normal file
93
resolve.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "resolve.h"
|
||||||
|
#include "ast.h"
|
||||||
|
#include "syms.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct Resolver {
|
||||||
|
Syms* ord_syms;
|
||||||
|
Syms* tag_syms;
|
||||||
|
Syms* label_syms;
|
||||||
|
|
||||||
|
bool in_typedef;
|
||||||
|
};
|
||||||
|
|
||||||
|
Resolver* resolver_new()
|
||||||
|
{
|
||||||
|
Resolver* r = malloc(sizeof(Resolver));
|
||||||
|
*r = (Resolver) {
|
||||||
|
.ord_syms = syms_new(),
|
||||||
|
.tag_syms = syms_new(),
|
||||||
|
.label_syms = syms_new(),
|
||||||
|
|
||||||
|
.in_typedef = false,
|
||||||
|
};
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolver_free(Resolver* r)
|
||||||
|
{
|
||||||
|
syms_free(r->ord_syms);
|
||||||
|
syms_free(r->tag_syms);
|
||||||
|
syms_free(r->label_syms);
|
||||||
|
free(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AstVisitorResult visit_stmt_block(AstVisitor* v, AstStmtBlock* node)
|
||||||
|
{
|
||||||
|
Resolver* r = v->op;
|
||||||
|
syms_push_scope(r->ord_syms);
|
||||||
|
|
||||||
|
ast_stmt_block_visit_body(v, node);
|
||||||
|
|
||||||
|
syms_pop_scope(r->ord_syms);
|
||||||
|
return AstVisitor_Break;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AstVisitorResult visit_stmt(AstVisitor* v, AstStmt* node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static AstVisitorResult visit_decl(AstVisitor* v, AstDecl* node)
|
||||||
|
{
|
||||||
|
Resolver* r = v->op;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AstVisitorResult visit_declar(AstVisitor* v, AstDeclar* node)
|
||||||
|
{
|
||||||
|
Resolver* r = v->op;
|
||||||
|
if (node->ty == AstDeclar_Function) {
|
||||||
|
syms_push_scope(r->ord_syms);
|
||||||
|
|
||||||
|
ast_declar_visit_body(v, node);
|
||||||
|
|
||||||
|
syms_pop_scope(r->ord_syms);
|
||||||
|
return AstVisitor_Break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->ty == AstDeclar_Ident) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
static AstVisitorResult visit_expr(AstVisitor* v, AstExpr* node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolver_resolve_top_stmt(Resolver* r, AstStmt* stmt)
|
||||||
|
{
|
||||||
|
if (stmt->ty != AstStmt_Decl) {
|
||||||
|
fprintf(
|
||||||
|
stderr, "error: expected declaration on line %d\n", stmt->loc.line);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
AstVisitor v = {
|
||||||
|
.visit_stmt_block = visit_stmt_block,
|
||||||
|
.visit_stmt = visit_stmt,
|
||||||
|
.visit_decl = visit_decl,
|
||||||
|
.visit_declar = visit_declar,
|
||||||
|
.visit_expr = visit_expr,
|
||||||
|
.op = r,
|
||||||
|
};
|
||||||
|
|
||||||
|
visit_stmt(&v, stmt);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user