small comptime interpreter refactor
This commit is contained in:
parent
b4ac6142cf
commit
1e73ac91e5
@ -171,17 +171,6 @@ pub fn huntItDown(
|
||||
return error.IdentifierNotFound;
|
||||
}
|
||||
|
||||
pub fn cast(
|
||||
interpreter: *ComptimeInterpreter,
|
||||
node_idx: Ast.Node.Index,
|
||||
destination_ty: IPIndex,
|
||||
source_ty: IPIndex,
|
||||
) error{ OutOfMemory, InvalidCast }!IPIndex {
|
||||
_ = node_idx;
|
||||
// TODO return errors
|
||||
return try interpreter.ip.cast(interpreter.allocator, destination_ty, source_ty, builtin.target);
|
||||
}
|
||||
|
||||
// Might be useful in the future
|
||||
pub const InterpretOptions = struct {};
|
||||
|
||||
@ -223,7 +212,6 @@ pub fn interpret(
|
||||
// .tagged_union_enum_tag,
|
||||
// .tagged_union_enum_tag_trailing,
|
||||
.root,
|
||||
// .error_set_decl, // TODO
|
||||
=> {
|
||||
const type_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type });
|
||||
|
||||
@ -289,6 +277,10 @@ pub fn interpret(
|
||||
.val = struct_type,
|
||||
} };
|
||||
},
|
||||
.error_set_decl => {
|
||||
// TODO
|
||||
return InterpretResult{ .nothing = {} };
|
||||
},
|
||||
.global_var_decl,
|
||||
.local_var_decl,
|
||||
.aligned_var_decl,
|
||||
@ -496,10 +488,10 @@ pub fn interpret(
|
||||
.@"if",
|
||||
.if_simple,
|
||||
=> {
|
||||
const iff = ast.ifFull(tree, node_idx);
|
||||
const if_info = ast.ifFull(tree, node_idx);
|
||||
// TODO: Don't evaluate runtime ifs
|
||||
// if (options.observe_values) {
|
||||
const ir = try interpreter.interpret(iff.ast.cond_expr, namespace, options);
|
||||
const ir = try interpreter.interpret(if_info.ast.cond_expr, namespace, options);
|
||||
|
||||
const false_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_false });
|
||||
const true_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_true });
|
||||
@ -507,10 +499,10 @@ pub fn interpret(
|
||||
const condition = (try ir.getValue()).val;
|
||||
std.debug.assert(condition == false_value or condition == true_value);
|
||||
if (condition == true_value) {
|
||||
return try interpreter.interpret(iff.ast.then_expr, namespace, options);
|
||||
return try interpreter.interpret(if_info.ast.then_expr, namespace, options);
|
||||
} else {
|
||||
if (iff.ast.else_expr != 0) {
|
||||
return try interpreter.interpret(iff.ast.else_expr, namespace, options);
|
||||
if (if_info.ast.else_expr != 0) {
|
||||
return try interpreter.interpret(if_info.ast.else_expr, namespace, options);
|
||||
} else return InterpretResult{ .nothing = {} };
|
||||
}
|
||||
},
|
||||
@ -525,8 +517,6 @@ pub fn interpret(
|
||||
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = if (a.value.val == b.value.val) .bool_true else .bool_false }), // TODO eql function required?
|
||||
},
|
||||
};
|
||||
|
||||
// a.getValue().eql(b.getValue())
|
||||
},
|
||||
.number_literal => {
|
||||
const s = tree.getNodeSource(node_idx);
|
||||
@ -534,7 +524,7 @@ pub fn interpret(
|
||||
|
||||
if (nl == .failure) return error.CriticalAstFailure;
|
||||
|
||||
const comptime_int_type = try interpreter.ip.get(interpreter.allocator, IPKey{
|
||||
const number_type = try interpreter.ip.get(interpreter.allocator, IPKey{
|
||||
.simple = if (nl == .float) .comptime_float else .comptime_int,
|
||||
});
|
||||
|
||||
@ -542,7 +532,7 @@ pub fn interpret(
|
||||
interpreter.allocator,
|
||||
switch (nl) {
|
||||
.float => IPKey{
|
||||
.float_64_value = try std.fmt.parseFloat(f64, s), // shouldn't this be f128?
|
||||
.float_128_value = try std.fmt.parseFloat(f128, s),
|
||||
},
|
||||
.int => if (s[0] == '-') IPKey{
|
||||
.int_i64_value = try std.fmt.parseInt(i64, s, 0),
|
||||
@ -557,7 +547,7 @@ pub fn interpret(
|
||||
return InterpretResult{ .value = Value{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = node_idx,
|
||||
.ty = comptime_int_type,
|
||||
.ty = number_type,
|
||||
.val = value,
|
||||
} };
|
||||
},
|
||||
@ -587,7 +577,8 @@ pub fn interpret(
|
||||
var to_value = try ir.getValue();
|
||||
var from_value = (try (try interpreter.interpret(data[node_idx].rhs, namespace, options)).getValue());
|
||||
|
||||
_ = try interpreter.cast(undefined, to_value.ty, from_value.ty);
|
||||
// TODO report error
|
||||
_ = try interpreter.ip.cast(interpreter.allocator, to_value.ty, from_value.ty, builtin.target);
|
||||
|
||||
return InterpretResult{ .nothing = {} };
|
||||
},
|
||||
@ -658,7 +649,7 @@ pub fn interpret(
|
||||
.fields = &.{},
|
||||
.namespace = .none,
|
||||
.layout = .Auto,
|
||||
.backing_int_ty = IPIndex.none,
|
||||
.backing_int_ty = .none,
|
||||
} }),
|
||||
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .undefined_value }),
|
||||
} };
|
||||
@ -675,7 +666,7 @@ pub fn interpret(
|
||||
.interpreter = interpreter,
|
||||
.node_idx = node_idx,
|
||||
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }),
|
||||
.val = undefined, // TODO
|
||||
.val = .none, // TODO
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -763,14 +754,12 @@ pub fn interpret(
|
||||
.address_space = .generic,
|
||||
} });
|
||||
|
||||
var val = Value{
|
||||
return InterpretResult{ .value = Value{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = node_idx,
|
||||
.ty = string_literal_type,
|
||||
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .bytes = str }),
|
||||
};
|
||||
|
||||
return InterpretResult{ .value = val };
|
||||
} };
|
||||
},
|
||||
// TODO: Add comptime autodetection; e.g. const MyArrayList = std.ArrayList(u8)
|
||||
.@"comptime" => {
|
||||
@ -874,23 +863,22 @@ pub fn interpret(
|
||||
const result = try interpreter.interpret(data[node_idx].lhs, namespace, .{});
|
||||
const bool_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool });
|
||||
const value = try result.getValue();
|
||||
if (value.ty == bool_type) {
|
||||
const false_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_false });
|
||||
const true_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_true });
|
||||
|
||||
const not_value = if (value.val == false_value) true_value else if (value.val == true_value) false_value else return error.InvalidOperation;
|
||||
return InterpretResult{
|
||||
.value = .{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = node_idx,
|
||||
.ty = bool_type,
|
||||
.val = not_value,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
// TODO
|
||||
if (value.ty != bool_type) {
|
||||
try interpreter.recordError(node_idx, "invalid_deref", try std.fmt.allocPrint(interpreter.allocator, "expected type `bool` but got `{}`", .{value.ty.fmtType(interpreter.ip)}));
|
||||
return error.InvalidOperation;
|
||||
}
|
||||
|
||||
const false_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_false });
|
||||
const true_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_true });
|
||||
|
||||
std.debug.assert(value.val == false_value or value.val == true_value);
|
||||
return InterpretResult{ .value = .{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = node_idx,
|
||||
.ty = bool_type,
|
||||
.val = if (value.val == false_value) true_value else false_value,
|
||||
} };
|
||||
},
|
||||
.address_of => {
|
||||
// TODO: Make const pointers if we're drawing from a const;
|
||||
|
Loading…
Reference in New Issue
Block a user