Fix type checker not promoting ints. Fix some issues in the codegen.
This commit is contained in:
69
Codegen.jai
69
Codegen.jai
@@ -41,13 +41,48 @@ indent :: (state : *Codegen_State, indentation : int) {
|
|||||||
for 1..indentation append(*state.builder, " ");
|
for 1..indentation append(*state.builder, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dx11_type_to_string :: (type_variable : Type_Variable) -> string {
|
||||||
|
if type_variable.type == {
|
||||||
|
case .Invalid;
|
||||||
|
return "{{invalid}}";
|
||||||
|
case .Unit;
|
||||||
|
return "()";
|
||||||
|
case .Int; {
|
||||||
|
return "int";
|
||||||
|
}
|
||||||
|
case .Half; {
|
||||||
|
return "half";
|
||||||
|
}
|
||||||
|
case .Float; {
|
||||||
|
return "float";
|
||||||
|
}
|
||||||
|
case .Double; {
|
||||||
|
return "double";
|
||||||
|
}
|
||||||
|
case .Sampler; {
|
||||||
|
return "SamplerState";
|
||||||
|
}
|
||||||
|
case .Texture2D; {
|
||||||
|
return "Texture2D";
|
||||||
|
}
|
||||||
|
case .Function; #through;
|
||||||
|
case .Struct; {
|
||||||
|
return type_variable.typename;
|
||||||
|
}
|
||||||
|
case .Array;
|
||||||
|
return "array";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
emit_field :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
|
emit_field :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
|
||||||
find_result := find_symbol(state.scope_stack, node.name, state.current_scope);
|
find_result := find_symbol(state.scope_stack, node.name, state.current_scope);
|
||||||
|
|
||||||
field := h2tv(state.type_variables, find_result.type_variable);
|
field := h2tv(state.type_variables, find_result.type_variable);
|
||||||
|
|
||||||
indent(state, indentation);
|
indent(state, indentation);
|
||||||
print_to_builder(*state.builder, "% ", type_to_string(field));
|
print_to_builder(*state.builder, "% ", dx11_type_to_string(field));
|
||||||
print_to_builder(*state.builder, "%", node.name);
|
print_to_builder(*state.builder, "%", node.name);
|
||||||
|
|
||||||
if field.type == .Sampler {
|
if field.type == .Sampler {
|
||||||
@@ -74,6 +109,8 @@ emit_field :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
|
|||||||
if hint.ident_value == "position" {
|
if hint.ident_value == "position" {
|
||||||
// @Incomplete(nb): Should be a lookup table somewhere
|
// @Incomplete(nb): Should be a lookup table somewhere
|
||||||
append(*state.builder, " : POSITION");
|
append(*state.builder, " : POSITION");
|
||||||
|
} else if hint.ident_value == "uv" {
|
||||||
|
append(*state.builder, " : TEXCOORD0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +134,7 @@ emit_call :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
|
|||||||
|
|
||||||
emit_node(state, args.children[0], 0);
|
emit_node(state, args.children[0], 0);
|
||||||
append(*state.builder, ".");
|
append(*state.builder, ".");
|
||||||
print_to_builder(*state.builder, "%(", node.name);
|
print_to_builder(*state.builder, "Sample(");
|
||||||
|
|
||||||
for i : 1..args.children.count - 1 {
|
for i : 1..args.children.count - 1 {
|
||||||
child := args.children[i];
|
child := args.children[i];
|
||||||
@@ -199,7 +236,7 @@ emit_function :: (state : *Codegen_State, node : *AST_Node, indentation : int, e
|
|||||||
|
|
||||||
if function_variable.return_type_variable {
|
if function_variable.return_type_variable {
|
||||||
return_variable := h2tv(state.type_variables, function_variable.return_type_variable);
|
return_variable := h2tv(state.type_variables, function_variable.return_type_variable);
|
||||||
print_to_builder(*state.builder, "% ", type_to_string(return_variable));
|
print_to_builder(*state.builder, "% ", dx11_type_to_string(return_variable));
|
||||||
} else {
|
} else {
|
||||||
append(*state.builder, "void ");
|
append(*state.builder, "void ");
|
||||||
}
|
}
|
||||||
@@ -390,7 +427,7 @@ emit_struct :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
|
|||||||
|
|
||||||
emit_field_list(state, field_list, indentation);
|
emit_field_list(state, field_list, indentation);
|
||||||
|
|
||||||
append(*state.builder, "}\n\n");
|
append(*state.builder, "};\n\n");
|
||||||
state.current_scope = current_scope;
|
state.current_scope = current_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,20 +471,20 @@ emit_declaration :: (state : *Codegen_State, node : *AST_Node) {
|
|||||||
|
|
||||||
codegen :: (state : *Codegen_State) -> Codegen_Result {
|
codegen :: (state : *Codegen_State) -> Codegen_Result {
|
||||||
found_function : bool = false;
|
found_function : bool = false;
|
||||||
found_struct : bool = false;
|
// found_struct : bool = false;
|
||||||
|
|
||||||
for variable : state.type_variables {
|
// for variable : state.type_variables {
|
||||||
if variable.type == .Struct && variable.kind == .Declaration && !variable.builtin {
|
// if variable.type == .Struct && variable.kind == .Declaration && !variable.builtin {
|
||||||
if variable.source_node.kind == .Properties continue;
|
// if variable.source_node.kind == .Properties continue;
|
||||||
if variable.source_node.kind == .Meta continue;
|
// if variable.source_node.kind == .Meta continue;
|
||||||
print_to_builder(*state.builder, "struct %;\n", variable.source_node.name);
|
// print_to_builder(*state.builder, "struct %;\n", variable.source_node.name);
|
||||||
found_struct = true;
|
// found_struct = true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if found_struct {
|
// if found_struct {
|
||||||
append(*state.builder, "\n");
|
// append(*state.builder, "\n");
|
||||||
}
|
// }
|
||||||
|
|
||||||
for variable : state.type_variables {
|
for variable : state.type_variables {
|
||||||
if variable.type == .Function && !variable.builtin
|
if variable.type == .Function && !variable.builtin
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
//~ nbr: Error reporting TODOs
|
//~ nbr: Error reporting TODOs
|
||||||
//
|
//
|
||||||
// [x] Improve error reporting on mismatched overloads when types don't match, but arity does
|
// [ ] Add and error for using keywords as names, or rename the dx11 keywords in the resulting hlsl shader.
|
||||||
|
// [x] Improve error reporting on mismatched overloads when types don't match, but arity does.
|
||||||
// [x] Improve error reporting for type mismatches in general. It seems like the expect node is not always correct.
|
// [x] Improve error reporting for type mismatches in general. It seems like the expect node is not always correct.
|
||||||
|
|
||||||
VERTEX_MAIN_FUNCTION_PREFIX :: "vertex";
|
VERTEX_MAIN_FUNCTION_PREFIX :: "vertex";
|
||||||
@@ -1270,7 +1271,6 @@ create_field :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable
|
|||||||
size_var := check_node(checker, size_node);
|
size_var := check_node(checker, size_node);
|
||||||
if h2tv(checker, size_var).type != .Int {
|
if h2tv(checker, size_var).type != .Int {
|
||||||
//@Incomplete(niels): Type mismatch here. With integral type required message.
|
//@Incomplete(niels): Type mismatch here. With integral type required message.
|
||||||
print("Shiet\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1456,6 +1456,7 @@ check_node :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_H
|
|||||||
variable, handle := new_type_variable(checker);
|
variable, handle := new_type_variable(checker);
|
||||||
lhs_type := h2tv(checker, lhs_var);
|
lhs_type := h2tv(checker, lhs_var);
|
||||||
variable.type = lhs_type.type;
|
variable.type = lhs_type.type;
|
||||||
|
variable.typename = lhs_type.typename;
|
||||||
variable.scope = lhs_type.scope;
|
variable.scope = lhs_type.scope;
|
||||||
variable.source_node = node;
|
variable.source_node = node;
|
||||||
node.type_variable = handle;
|
node.type_variable = handle;
|
||||||
@@ -1470,7 +1471,9 @@ check_node :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_H
|
|||||||
create_equivalence_constraint(checker, rhs_var, lhs_var, node);
|
create_equivalence_constraint(checker, rhs_var, lhs_var, node);
|
||||||
|
|
||||||
proper_variable, rhs_handle := new_type_variable(checker);
|
proper_variable, rhs_handle := new_type_variable(checker);
|
||||||
proper_variable.type = h2tv(checker, lhs_var).type;
|
lhs_type_var := h2tv(checker, lhs_var);
|
||||||
|
proper_variable.type = lhs_type_var.type;
|
||||||
|
proper_variable.typename = lhs_type_var.typename;
|
||||||
proper_variable.source_node = h2tv(checker, lhs_var).source_node;
|
proper_variable.source_node = h2tv(checker, lhs_var).source_node;
|
||||||
proper_variable.struct_field_parent = h2tv(checker, lhs_var).struct_field_parent;
|
proper_variable.struct_field_parent = h2tv(checker, lhs_var).struct_field_parent;
|
||||||
|
|
||||||
@@ -1579,6 +1582,15 @@ types_compatible :: (checker : *Semantic_Checker, lhs : Type_Variable_Handle, rh
|
|||||||
case .Half; #through;
|
case .Half; #through;
|
||||||
case .Float; #through;
|
case .Float; #through;
|
||||||
case .Double; {
|
case .Double; {
|
||||||
|
if rhs_var.type == .Struct {
|
||||||
|
if rhs_var.typename == {
|
||||||
|
case "float2"; #through;
|
||||||
|
case "float3"; #through;
|
||||||
|
case "float4"; {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return rhs_var.type == .Int || rhs_var.type == .Half ||
|
return rhs_var.type == .Int || rhs_var.type == .Half ||
|
||||||
rhs_var.type == .Float || rhs_var.type == .Double;
|
rhs_var.type == .Float || rhs_var.type == .Double;
|
||||||
}
|
}
|
||||||
@@ -1594,6 +1606,16 @@ types_compatible :: (checker : *Semantic_Checker, lhs : Type_Variable_Handle, rh
|
|||||||
lhs_node := lhs_var.source_node;
|
lhs_node := lhs_var.source_node;
|
||||||
rhs_node := rhs_var.source_node;
|
rhs_node := rhs_var.source_node;
|
||||||
|
|
||||||
|
if rhs_var.type != .Struct {
|
||||||
|
if lhs_var.typename == {
|
||||||
|
case "float2"; #through;
|
||||||
|
case "float3"; #through;
|
||||||
|
case "float4"; {
|
||||||
|
return rhs_var.type == .Int || rhs_var.type == .Half || rhs_var.type == .Double || rhs_var.type == .Float;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lhs_struct := find_symbol(checker, lhs_var.typename, xx 1);
|
lhs_struct := find_symbol(checker, lhs_var.typename, xx 1);
|
||||||
rhs_struct := find_symbol(checker, rhs_var.typename, xx 1);
|
rhs_struct := find_symbol(checker, rhs_var.typename, xx 1);
|
||||||
|
|
||||||
@@ -1637,7 +1659,6 @@ union_terms :: (checker : *Semantic_Checker, lhs_handle : Type_Variable_Handle,
|
|||||||
lhs_var := h2tv(checker, lhs_handle);
|
lhs_var := h2tv(checker, lhs_handle);
|
||||||
rhs_var := h2tv(checker, rhs_handle);
|
rhs_var := h2tv(checker, rhs_handle);
|
||||||
|
|
||||||
print("% %\n", type_to_string(h2tv(checker, lhs_handle)), type_to_string(h2tv(checker, rhs_handle)));
|
|
||||||
if usage_site {
|
if usage_site {
|
||||||
type_mismatch(checker, usage_site, rhs_var.source_node.parent, rhs_handle, lhs_handle);
|
type_mismatch(checker, usage_site, rhs_var.source_node.parent, rhs_handle, lhs_handle);
|
||||||
} else {
|
} else {
|
||||||
@@ -1815,6 +1836,7 @@ check :: (checker : *Semantic_Checker) -> Semantic_Check_Result {
|
|||||||
// ===========================================================
|
// ===========================================================
|
||||||
// Pretty printing
|
// Pretty printing
|
||||||
|
|
||||||
|
#scope_file
|
||||||
|
|
||||||
type_to_string :: (type_variable : Type_Variable) -> string {
|
type_to_string :: (type_variable : Type_Variable) -> string {
|
||||||
if type_variable.type == {
|
if type_variable.type == {
|
||||||
@@ -1832,7 +1854,6 @@ type_to_string :: (type_variable : Type_Variable) -> string {
|
|||||||
}
|
}
|
||||||
case .Function; #through;
|
case .Function; #through;
|
||||||
case .Struct; {
|
case .Struct; {
|
||||||
print("%\n", type_variable);
|
|
||||||
return type_variable.typename;
|
return type_variable.typename;
|
||||||
}
|
}
|
||||||
case .Array;
|
case .Array;
|
||||||
@@ -1842,6 +1863,8 @@ type_to_string :: (type_variable : Type_Variable) -> string {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#scope_export
|
||||||
|
|
||||||
print_key :: (checker : *Semantic_Checker, builder : *String_Builder, name : string) {
|
print_key :: (checker : *Semantic_Checker, builder : *String_Builder, name : string) {
|
||||||
scope := get_current_scope(checker);
|
scope := get_current_scope(checker);
|
||||||
target_length := scope.longest_key_length + 1;
|
target_length := scope.longest_key_length + 1;
|
||||||
|
|||||||
@@ -259,4 +259,4 @@ int4x4 :: struct {
|
|||||||
#foreign atan2 :: (float4, float4) -> float4;
|
#foreign atan2 :: (float4, float4) -> float4;
|
||||||
#foreign atan2 :: (float4x4, float4x4) -> float4x4;
|
#foreign atan2 :: (float4x4, float4x4) -> float4x4;
|
||||||
|
|
||||||
#foreign sample :: (Texture2D, float2, Sampler) -> float4;
|
#foreign sample :: (Texture2D, Sampler, float2) -> float4;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ p :: properties {
|
|||||||
|
|
||||||
PS_Input :: struct {
|
PS_Input :: struct {
|
||||||
uv : float2 @uv;
|
uv : float2 @uv;
|
||||||
pos : float2 @pos;
|
pos : float4 @pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertex main :: (pos : float4 @position) -> PS_Input {
|
vertex main :: (pos : float4 @position) -> PS_Input {
|
||||||
@@ -28,7 +28,7 @@ vertex main :: (pos : float4 @position) -> PS_Input {
|
|||||||
|
|
||||||
src_half_size : float2 = (src_p1 - src_p0) / 2;
|
src_half_size : float2 = (src_p1 - src_p0) / 2;
|
||||||
src_center : float2 = (src_p1 + src_p0) / 2;
|
src_center : float2 = (src_p1 + src_p0) / 2;
|
||||||
src_pos : float2 = pos * src_half_size + src_center;
|
src_pos : float2 = float2(pos.x, pos.y) * src_half_size + src_center;
|
||||||
|
|
||||||
result.uv = float2(1, 1);
|
result.uv = float2(1, 1);
|
||||||
result.pos = float4(2.0 * dst_pos.x / res.x - 1, 2.0 * dst_pos.y / res.y - 1, 0.0, 1.0);
|
result.pos = float4(2.0 * dst_pos.x / res.x - 1, 2.0 * dst_pos.y / res.y - 1, 0.0, 1.0);
|
||||||
|
|||||||
14
test/simple_float2_expressions.shd
Normal file
14
test/simple_float2_expressions.shd
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
vertex main :: (pos : float4 @position) -> float4 @position {
|
||||||
|
src_p0 : float2 = float2(0.0, 1.0);
|
||||||
|
src_p1 : float2 = float2(1.0, 0.0);
|
||||||
|
|
||||||
|
src_half_size : float2 = (src_p1 - src_p0) / 2;
|
||||||
|
src_center : float2 = (src_p1 + src_p0) / 2;
|
||||||
|
src_pos : float2 = float2(pos.x, pos.y) * src_half_size + src_center;
|
||||||
|
|
||||||
|
return float4(1, 1, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel main :: () -> float4 @target0 {
|
||||||
|
return float4(1, 1, 1, 1);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user