about summary refs log tree commit diff
path: root/boot/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/ir.c')
-rw-r--r--boot/ir.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/boot/ir.c b/boot/ir.c
index 54ee2b3..4bdfc6e 100644
--- a/boot/ir.c
+++ b/boot/ir.c
@@ -541,3 +541,242 @@ block_new(void)
     *block = (struct Block){ 0 };
     return block;
 }
+
+struct Expression*
+ir_make_integer(int64 value, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.integer_literal.value = value;
+    return expression_new(EXPRESSION_INTEGER_LITERAL, v, span);
+}
+
+struct Expression*
+ir_make_float(float64 value, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.float_literal.value = value;
+    return expression_new(EXPRESSION_FLOAT_LITERAL, v, span);
+}
+
+struct Expression*
+ir_make_string(struct String value, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.string_literal.value = value;
+    return expression_new(EXPRESSION_STRING_LITERAL, v, span);
+}
+
+struct Expression*
+ir_make_bool(bool value, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.bool_literal.value = value;
+    return expression_new(EXPRESSION_BOOLEAN_LITERAL, v, span);
+}
+
+struct Expression*
+ir_make_name(struct String name, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.name.name = name;
+    return expression_new(EXPRESSION_NAME, v, span);
+}
+
+struct Expression*
+ir_make_unary(enum Unary_Operation op, struct Expression* operand, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.unary_operator.operation = op;
+    v.unary_operator.operand = operand;
+    return expression_new(EXPRESSION_UNARY_OPERATION, v, span);
+}
+
+struct Expression*
+ir_make_binary(
+    enum Binary_Operation op, struct Expression* left, struct Expression* right, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.binary_operator.operation = op;
+    v.binary_operator.left_operand = left;
+    v.binary_operator.right_operand = right;
+    return expression_new(EXPRESSION_BINARY_OPERATION, v, span);
+}
+
+struct Expression*
+ir_make_sizeof(struct Type_Ref target, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.sizeof_operator.target = target;
+    return expression_new(EXPRESSION_SIZEOF_OPERATION, v, span);
+}
+
+struct Expression*
+ir_make_call(struct Expression* subject, Array(struct Expression*) arguments, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.call.subject = subject;
+    v.call.arguments = arguments;
+    return expression_new(EXPRESSION_CALL, v, span);
+}
+
+struct Expression*
+ir_make_member(struct Expression* subject, struct String name, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.member.subject = subject;
+    v.member.name = name;
+    return expression_new(EXPRESSION_MEMBER, v, span);
+}
+
+struct Expression*
+ir_make_subscript(struct Expression* subject, struct Expression* index, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.subscript.subject = subject;
+    v.subscript.index = index;
+    return expression_new(EXPRESSION_SUBSCRIPT, v, span);
+}
+
+struct Expression*
+ir_make_cast(struct Type_Ref target, struct Expression* operand, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.cast.target = target;
+    v.cast.operand = operand;
+    return expression_new(EXPRESSION_CAST, v, span);
+}
+
+struct Expression*
+ir_make_construct(Type_Id type_id, Array(struct Construct_Field) fields, struct Span span)
+{
+    union Expression_Value v = { 0 };
+    v.construct.type_id = type_id;
+    v.construct.fields = fields;
+    return expression_new(EXPRESSION_CONSTRUCT, v, span);
+}
+
+// type-ref constructors.
+// `bare` is the no-modifier form; `pointer` wraps one `&` modifier; `with_mods`
+// takes a fully-formed mods array (caller owns it).
+
+struct Type_Ref
+type_ref_bare(Type_Id type_id)
+{
+    return (struct Type_Ref){
+        .type_id = type_id,
+        .mods = array_new(enum Type_Modifier, 4),
+    };
+}
+
+struct Type_Ref
+type_ref_pointer(Type_Id type_id)
+{
+    struct Type_Ref ref = type_ref_bare(type_id);
+    enum Type_Modifier mod = TYPE_MOD_REFERENCE;
+    array_push(&ref.mods, &mod);
+    return ref;
+}
+
+struct Type_Ref
+type_ref_with_mods(Type_Id type_id, Array(enum Type_Modifier) mods)
+{
+    return (struct Type_Ref){
+        .type_id = type_id,
+        .mods = mods,
+    };
+}
+
+// statement builder family.
+// same shape as the expression builders: wrap the union-init around
+// `statement_new` so call sites stay readable.
+
+struct Statement*
+ir_make_declaration(
+    struct String name, struct Type_Ref type, struct Expression* initializer, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.declaration.name = name;
+    v.declaration.type = type;
+    v.declaration.initializer = initializer;
+    return statement_new(STATEMENT_DECLARATION, v, span);
+}
+
+struct Statement*
+ir_make_assign(struct Expression* lhs, struct Expression* rhs, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.assign.lhs = lhs;
+    v.assign.rhs = rhs;
+    return statement_new(STATEMENT_ASSIGN, v, span);
+}
+
+struct Statement*
+ir_make_expression_statement(struct Expression* inner, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.expression.inner = inner;
+    return statement_new(STATEMENT_EXPRESSION, v, span);
+}
+
+struct Statement*
+ir_make_conditional(Array(struct If_Branch) branches, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.conditional.branches = branches;
+    return statement_new(STATEMENT_CONDITIONAL, v, span);
+}
+
+struct Statement*
+ir_make_loop(struct Expression* condition, struct Block* body, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.loop.condition = condition;
+    v.loop.body = body;
+    return statement_new(STATEMENT_LOOP, v, span);
+}
+
+struct Statement*
+ir_make_return(struct Expression* value, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.return_value.value = value;
+    return statement_new(STATEMENT_RETURN, v, span);
+}
+
+struct Statement*
+ir_make_break(struct Span span)
+{
+    union Statement_Value v = { 0 };
+    return statement_new(STATEMENT_BREAK, v, span);
+}
+
+struct Statement*
+ir_make_continue(struct Span span)
+{
+    union Statement_Value v = { 0 };
+    return statement_new(STATEMENT_CONTINUE, v, span);
+}
+
+struct Statement*
+ir_make_block_statement(struct Block* inner, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.block.inner = inner;
+    return statement_new(STATEMENT_BLOCK, v, span);
+}
+
+struct Statement*
+ir_make_label(struct String name, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.label.name = name;
+    return statement_new(STATEMENT_LABEL, v, span);
+}
+
+struct Statement*
+ir_make_goto(struct String target, struct Span span)
+{
+    union Statement_Value v = { 0 };
+    v.goto_target.target = target;
+    return statement_new(STATEMENT_GOTO, v, span);
+}