#include "spl_ast2ir.h" static spl_ir_node_ref_t spl_ir_const_comptime_int(spl_ir_builder_t *ir, const spl_sema_t *sema, usize i) { return spl_ir_builder_type_const_int(ir, spl_type_builder_int(sema->type, 0, 0), i); } static spl_type_id_t tid_from_def(const spl_sema_t *sema, spl_def_id_t def) { spl_def_node_t *d = spl_def_node(sema->type, def); return d ? d->type_id : 0; } static spl_ir_node_ref_t transit(spl_ir_builder_t *ir, const spl_sema_t *sema, spl_ast_node_ref_t ref) { if (ref == 0) return 0; Assert(sema != NULL); spl_ast_node_t *n = spl_ast_node(sema->ast, ref); spl_ir_node_ref_t ret = 0; Assert(n != NULL); switch (n->kind) { case SPL_AST_NONE: UNREACHABLE(); break; case SPL_AST_CONTAINER_MEMBERS: { vec_for(n->container_members, i) { transit(ir, sema, vec_at(n->container_members, i)); } } break; case SPL_AST_FN_DECL: TODO(); break; case SPL_AST_FN_DEFINE: { spl_type_id_t tid = tid_from_def(sema, n->resolved_def_id); spl_type_node_t *fn_type = spl_type_node(sema->type, tid); Assert(fn_type && fn_type->kind == SPL_TYPE_FN); // n->fn_decl.attr_list; TODO @extern(vm) using extern attribute spl_ir_builder_fn_begin(ir, n->fn_decl.name, tid, (spl_ir_attr_t){0} /*TODO*/); spl_ir_builder_block_begin(ir); vec_for(n->fn_decl.block, i) { transit(ir, sema, vec_at(n->fn_decl.block, i)); } if (!ir->terminated) { spl_ir_builder_control_ret(ir, n->fn_decl.type_expr, 0); } spl_ir_builder_block_end(ir); spl_ir_builder_fn_end(ir); } break; case SPL_AST_TYPE_DECL: TODO(); break; case SPL_AST_VAR_DECL: { spl_type_id_t tid = tid_from_def(sema, n->resolved_def_id); spl_ir_node_ref_t var_ref = spl_ir_builder_mem_alloca(ir, tid, spl_ir_const_comptime_int(ir, sema, 1)); if (n->var_const_decl.expr) { spl_ir_builder_mem_store(ir, tid, var_ref, transit(ir, sema, n->var_const_decl.expr)); } } break; case SPL_AST_CONST_DECL: { TODO(); } break; case SPL_AST_MEMBER_DECL: TODO(); break; case SPL_AST__COMPTIME_STMT: case SPL_AST__DIRECTIVE_BLOCK: case SPL_AST_PARAM_DECL: break; case SPL_AST_ATTR_ITEM: case SPL_AST_ARGG_INIT_ITEM: { TODO(); } break; case SPL_AST_IF_STATEMENT: { spl_ir_node_ref_t ref = transit(ir, sema, n->if_statement.expr); ref = spl_ir_builder_control_br(ir, ref); spl_ir_builder_block_end(ir); usize true_block = spl_ir_builder_block_begin(ir); usize false_block = spl_ir_builder_block_begin(ir); spl_ir_builder_control_br_fixup(ir, ref, true_block, false_block); } break; case SPL_AST_IFVAR_STATEMENT: case SPL_AST_WHILE_STATEMENT: case SPL_AST_LOOP_STATEMENT: case SPL_AST_FOR_STATEMENT: case SPL_AST_MATCH_STATEMENT: TODO(); break; case SPL_AST_RET_STATEMENT: { if (n->ret_statement.expr) { ret = transit(ir, sema, n->ret_statement.expr); } ret = spl_ir_builder_control_ret(ir, n->resolved_type_id, ret); } break; case SPL_AST_BREAK_STATEMENT: case SPL_AST_CONTINUE_STATEMENT: case SPL_AST_DEFER_STATEMENT: case SPL_AST_TRY_STATEMENT: case SPL_AST_CATCH_STATEMENT: case SPL_AST_ERRDEFER_STATEMEMT: case SPL_AST_EXPR_STATEMENT: case SPL_AST_PACKED_EXPR: case SPL_AST_ASSIGN_EXPR: case SPL_AST_ASSIGN_ADD_EXPR: case SPL_AST_ASSIGN_SUB_EXPR: case SPL_AST_ASSIGN_MUL_EXPR: case SPL_AST_ASSIGN_DIV_EXPR: case SPL_AST_ASSIGN_MOD_EXPR: case SPL_AST_ASSIGN_AND_EXPR: case SPL_AST_ASSIGN_OR_EXPR: case SPL_AST_ASSIGN_XOR_EXPR: case SPL_AST_ASSIGN_LSHIFT_EXPR: case SPL_AST_ASSIGN_USHIFT_EXPR: case SPL_AST_BOOL_OR_EXPR: case SPL_AST_BOOL_AND_EXPR: case SPL_AST_BIT_OR_EXPR: case SPL_AST_BIT_XOR_EXPR: case SPL_AST_BIT_AND_EXPR: case SPL_AST_CMP_EQ_EXPR: case SPL_AST_CMP_NE_EXPR: case SPL_AST_CMP_LE_EXPR: case SPL_AST_CMP_GE_EXPR: case SPL_AST_CMP_LT_EXPR: case SPL_AST_CMP_GT_EXPR: case SPL_AST_RANGE_EXPR: case SPL_AST_LSHIFT_EXPR: case SPL_AST_RSHIFT_EXPR: case SPL_AST_ADD_EXPR: case SPL_AST_SUB_EXPR: case SPL_AST_MUL_EXPR: case SPL_AST_DIV_EXPR: case SPL_AST_MOD_EXPR: case SPL_AST_MINUS_EXPR: case SPL_AST_NOT_EXPR: case SPL_AST_BIT_NOT_EXPR: case SPL_AST_ADDRESS_EXPR: case SPL_AST_CALL_EXPR: case SPL_AST_FIELD_EXPR: case SPL_AST_DEREF_EXPR: case SPL_AST_INDEX_EXPR: case SPL_AST_SLICE_EXPR: case SPL_AST_AS_EXPR: TODO(); break; case SPL_AST_EXPR_INTEGER_LIT: { ret = spl_ir_builder_type_const_int(ir, n->resolved_type_id, n->primary_expr.integer_expr); break; } case SPL_AST_EXPR_FLOAT_LIT: case SPL_AST_EXPR_CHAR_LIT: case SPL_AST_EXPR_STRING_LIT: { TODO(); } break; case SPL_AST_EXPR_TRUE: { return spl_ir_builder_type_const_bool( ir, spl_type_builder_simple(sema->type, SPL_TYPE_BOOL), true); } break; case SPL_AST_EXPR_FALSE: { return spl_ir_builder_type_const_bool( ir, spl_type_builder_simple(sema->type, SPL_TYPE_BOOL), false); } case SPL_AST_EXPR_NULL: { return spl_ir_builder_type_const_bool(ir, n->resolved_type_id, 0); } break; case SPL_AST_EXPR_UNDEFINED: break; case SPL_AST_EXPR_IDENT: { } break; case SPL_AST_ARGGREGATE_INIT: { vec_for(n->primary_expr.aggregate_init.expr, i) { transit(ir, sema, vec_at(n->primary_expr.aggregate_init.expr, i)); } } break; case SPL_AST_EXPR_EXPR: { transit(ir, sema, n->primary_expr.expr); } break; case SPL_AST_ARRAY_LIT: { TODO(); } break; case SPL_AST_BUILTIN_EXPR: { TODO(); } break; case SPL_AST_BLOCK_EXPR: { vec_for(n->primary_expr.block_expr, i) { transit(ir, sema, vec_at(n->primary_expr.block_expr, i)); } } break; case SPL_AST_BASE_TYPE_FN: case SPL_AST_BASE_TYPE_PATH: TODO(); break; case SPL_AST_TYPE_POINTER: case SPL_AST_TYPE_ARRAY: case SPL_AST_TYPE_SLICE: case SPL_AST_TYPE_STRUCT: case SPL_AST_TYPE_UNION: case SPL_AST_TYPE_SHAPE: case SPL_AST_TYPE_ENUM: case SPL_AST_TYPE_VOID: case SPL_AST_TYPE_BOOL: case SPL_AST_TYPE_OPAQUE: case SPL_AST_TYPE_I8: case SPL_AST_TYPE_U8: case SPL_AST_TYPE_I16: case SPL_AST_TYPE_U16: case SPL_AST_TYPE_I32: case SPL_AST_TYPE_U32: case SPL_AST_TYPE_I64: case SPL_AST_TYPE_U64: case SPL_AST_TYPE_ISIZE: case SPL_AST_TYPE_USIZE: case SPL_AST_TYPE__F32: case SPL_AST_TYPE__F64: case SPL_AST_TYPE_ANY: case SPL_AST_TYPE_IDENT: break; case SPL_AST_COUNT: UNREACHABLE(); break; } return ret; } void spl_ast2ir_init(spl_ast2ir_t *ast2ir, spl_ir_builder_t *ir, const spl_sema_t *sema) { ast2ir->sema = sema; ast2ir->ir = ir; ast2ir->err_count = 0; } void spl_ast2ir_drop(spl_ast2ir_t *ast2ir) {} void spl_ast2ir_run(spl_ast2ir_t *ctx) { transit(ctx->ir, ctx->sema, ctx->sema->ast->root); }