Compare commits

...

2 Commits

26 changed files with 262 additions and 28 deletions

View File

@@ -211,7 +211,11 @@ pretty_print_binary :: (node : *AST_Node, indentation : int, builder : *String_B
}
pretty_print_unary :: (node : *AST_Node, indentation : int, builder : *String_Builder) {
indent(builder, indentation);
op := node.token;
print_to_builder(builder, op_to_string(op));
pretty_print_children(node, 0, builder, flags = 0);
}
print_return_node :: (node : *AST_Node, indentation : int, builder : *String_Builder) {

View File

@@ -420,7 +420,10 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
}
}
case .Unary; {
assert(false, "Not implemented yet: unary");
indent(*state.builder, indentation);
emit_operator(state, node.token.kind);
emit_node(state, node.children[0], 0);
}
case .Expression_Statement; {
emit_node(state, node.children[0], indentation);

View File

@@ -330,6 +330,7 @@ no_matching_overload_found :: (checker : *Semantic_Checker, call : *AST_Node, ov
record_error(checker, message, locations, false);
}
not_all_control_paths_return_value :: (checker : *Semantic_Checker, node : *AST_Node) {
builder : String_Builder;
init_string_builder(*builder,, temp);
@@ -1374,6 +1375,19 @@ check_node :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_H
field_var := create_field(checker, node);
return field_var;
}
case .Unary; {
var := check_node(checker, node.children[0]);
variable, handle := new_type_variable(checker);
type := from_handle(checker, var);
variable.type = type.type;
variable.typename = type.typename;
variable.scope = type.scope;
variable.source_node = node;
node.type_variable = handle;
add_child(variable, var);
return handle;
}
case .Binary; {
lhs_var := check_node(checker, node.children[0]);
if lhs_var == 0 {

View File

@@ -150,6 +150,23 @@ Compiled_File :: struct {
codegen_result_text : string;
semantic_check_result : Semantic_Check_Result;
vertex_entry_point : struct {
name : string;
input : [..]Field;
}
pixel_entry_point : struct {
name : string;
return_value : Field;
}
properties : Properties;
max_constant_buffers :: 16;
cbuffers : Static_Array(Constant_Buffer, max_constant_buffers);
}
Compile_Result :: struct {
@@ -286,7 +303,7 @@ type_variable_to_field :: (checker : *Semantic_Checker, variable : Type_Variable
return type_variable_to_field(checker, from_handle(checker, variable));
}
type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variable) -> Field {
type_variable_to_field :: (type_variables : []Type_Variable, scope_stack : Scope_Stack, variable : *Type_Variable) -> Field {
field : Field;
field.name = variable.name;
@@ -319,14 +336,14 @@ type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variabl
case .Struct; {
type.kind = Field_Kind.Struct;
find_result := find_symbol(checker, variable.typename, xx 1);
find_result := find_symbol(scope_stack, variable.typename, xx 1);
assert(find_result != null, "Internal compiler error\n");
type_var := from_handle(checker, find_result.type_variable);
type_var := from_handle(type_variables, find_result.type_variable);
for i : 0..type_var.children.count - 1 {
child := type_var.children[i];
child_field := type_variable_to_field(checker, from_handle(checker, child));
child_field := type_variable_to_field(type_variables, scope_stack, child);
array_add(*type.children, child_field);
}
@@ -364,6 +381,14 @@ type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variabl
return field;
}
type_variable_to_field :: (type_variables : []Type_Variable, scope_stack : Scope_Stack, variable : Type_Variable_Handle) -> Field {
return type_variable_to_field(type_variables, scope_stack, from_handle(type_variables, variable));
}
type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variable) -> Field {
return type_variable_to_field(checker.result.type_variables, checker.result.scope_stack, variable);
}
compile_file :: (compiler : *Shader_Compiler, paths : []string) -> Compile_Result {
result : Compile_Result;
@@ -376,6 +401,90 @@ compile_file :: (compiler : *Shader_Compiler, paths : []string) -> Compile_Resul
check(*result);
codegen(*result);
for *file : result.files {
check_result := file.semantic_check_result;
if check_result.vertex_entry_point {
file.vertex_entry_point.name = check_result.vertex_entry_point.name;
type_variable := from_handle(check_result.type_variables, check_result.vertex_entry_point.type_variable);
assert(type_variable.type == .Function);
node := type_variable.source_node;
if node.children.count > 0 {
if node.children[0].kind == .FieldList {
field_list := node.children[0];
for child : field_list.children {
tv := from_handle(check_result.type_variables, child.type_variable);
field := type_variable_to_field(check_result.type_variables, check_result.scope_stack, tv);
array_add(*file.vertex_entry_point.input, field);
}
}
}
}
for buffer_variable : to_array(*check_result.constant_buffers) {
variable := from_handle(check_result.type_variables, buffer_variable);
cb := array_add(*file.cbuffers);
for i : 0..variable.children.count - 1 {
child := variable.children[i];
field : Property_Field;
field.base_field = type_variable_to_field(check_result.type_variables, check_result.scope_stack, from_handle(check_result.type_variables, child));
array_add(*cb.fields, field);
}
cb.buffer_index = variable.resource_index;
}
find_result := find_symbol(*check_result.scope_stack, check_result.property_name, xx 1);
if find_result {
property_variable := from_handle(check_result.type_variables, find_result.type_variable);
for i : 0..property_variable.children.count - 1 {
child := property_variable.children[i];
field := type_variable_to_field(check_result.type_variables, check_result.scope_stack, from_handle(check_result.type_variables, child));
prop_field : Property_Field;
prop_field.base_field = field;
array_add(*file.properties.fields, prop_field);
}
file.properties.buffer_index = property_variable.resource_index;
}
if check_result.pixel_entry_point {
file.pixel_entry_point.name = check_result.pixel_entry_point.name;
type_variable := from_handle(check_result.type_variables, check_result.pixel_entry_point.type_variable);
assert(type_variable.type == .Function);
field := type_variable_to_field(check_result.type_variables, check_result.scope_stack, type_variable.return_type_variable);
for hint : type_variable.source_node.hint_tokens {
field_hint : Field_Hint;
if hint.ident_value == "position" {
// @Incomplete(nb): Should be a lookup table somewhere
field_hint.kind = .Position;
} else if starts_with(hint.ident_value, "target") {
// @Incomplete(nb): Should be a lookup table somewhere
index_str : string;
index_str.data = *hint.ident_value.data[7];
index_str.count = 1;
result, ok, remainder := string_to_int(index_str);
if ok {
field_hint.target_index = result;
}
field_hint.kind = .Target;
} else {
// @Incomplete(nb): custom hints
}
array_add(*field.hints, field_hint);
}
file.pixel_entry_point.return_value = field;
}
}
return result;
}

10
test/codegen/unary.golden Normal file
View File

@@ -0,0 +1,10 @@
float4 vs_vs_main(float3 position : POSITION) : SV_POSITION
{
return float4(position.x, position.y, position.z, 1.0f);
}
float4 ps_ps_main(float4 position : SV_POSITION) : SV_TARGET
{
return float4(0.5f, -1, 0, 1);
}

View File

@@ -17,4 +17,5 @@ test/passthrough.ink codegen
test/property_rename.ink codegen
test/simple_struct_access.ink codegen
test/struct_within_struct.ink codegen
test/unary.ink codegen
test/use_builtin_functions.ink codegen

View File

@@ -17,4 +17,5 @@ test/pass_and_access_struct_fields_in_functions.ink compile
test/passthrough.ink compile
test/simple_struct_access.ink compile
test/struct_within_struct.ink compile
test/unary.ink compile
test/use_builtin_functions.ink compile

View File

@@ -1,4 +1,4 @@
test/float_suffix.inx:2,12: error: We don't use 'f' suffixes for floating point values.
test/float_suffix.ink:2,12: error: We don't use 'f' suffixes for floating point values.
 x : float = 2.0f
^^^^


64
test/lex/unary.golden Normal file
View File

@@ -0,0 +1,64 @@
{kind = TOKEN_VERTEX; ; index = 0 ; length = 6 line = 1 ; column = 0 ; value ='vertex'; }
{kind = TOKEN_IDENTIFIER; ; index = 7 ; length = 7 line = 1 ; column = 7 ; value ='vs_main'; }
{kind = TOKEN_DOUBLECOLON; ; index = 15 ; length = 2 line = 1 ; column = 15 ; value ='::'; }
{kind = TOKEN_LEFTPAREN; ; index = 18 ; length = 1 line = 1 ; column = 18 ; value ='('; }
{kind = TOKEN_IDENTIFIER; ; index = 19 ; length = 8 line = 1 ; column = 19 ; value ='position'; }
{kind = TOKEN_COLON; ; index = 28 ; length = 1 line = 1 ; column = 28 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 30 ; length = 6 line = 1 ; column = 30 ; value ='float3'; }
{kind = TOKEN_AT; ; index = 37 ; length = 1 line = 1 ; column = 37 ; value ='@'; }
{kind = TOKEN_IDENTIFIER; ; index = 38 ; length = 8 line = 1 ; column = 38 ; value ='position'; }
{kind = TOKEN_RIGHTPAREN; ; index = 46 ; length = 1 line = 1 ; column = 46 ; value =')'; }
{kind = TOKEN_ARROW; ; index = 48 ; length = 2 line = 1 ; column = 48 ; value ='->'; }
{kind = TOKEN_IDENTIFIER; ; index = 51 ; length = 6 line = 1 ; column = 51 ; value ='float4'; }
{kind = TOKEN_AT; ; index = 58 ; length = 1 line = 1 ; column = 58 ; value ='@'; }
{kind = TOKEN_IDENTIFIER; ; index = 59 ; length = 8 line = 1 ; column = 59 ; value ='position'; }
{kind = TOKEN_LEFTBRACE; ; index = 68 ; length = 1 line = 1 ; column = 68 ; value ='{'; }
{kind = TOKEN_RETURN; ; index = 75 ; length = 6 line = 2 ; column = 3 ; value ='return'; }
{kind = TOKEN_IDENTIFIER; ; index = 82 ; length = 6 line = 2 ; column = 10 ; value ='float4'; }
{kind = TOKEN_LEFTPAREN; ; index = 88 ; length = 1 line = 2 ; column = 16 ; value ='('; }
{kind = TOKEN_IDENTIFIER; ; index = 89 ; length = 8 line = 2 ; column = 17 ; value ='position'; }
{kind = TOKEN_DOT; ; index = 97 ; length = 1 line = 2 ; column = 25 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 98 ; length = 1 line = 2 ; column = 26 ; value ='x'; }
{kind = TOKEN_COMMA; ; index = 99 ; length = 1 line = 2 ; column = 27 ; value =','; }
{kind = TOKEN_IDENTIFIER; ; index = 101 ; length = 8 line = 2 ; column = 29 ; value ='position'; }
{kind = TOKEN_DOT; ; index = 109 ; length = 1 line = 2 ; column = 37 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 110 ; length = 1 line = 2 ; column = 38 ; value ='y'; }
{kind = TOKEN_COMMA; ; index = 111 ; length = 1 line = 2 ; column = 39 ; value =','; }
{kind = TOKEN_IDENTIFIER; ; index = 113 ; length = 8 line = 2 ; column = 41 ; value ='position'; }
{kind = TOKEN_DOT; ; index = 121 ; length = 1 line = 2 ; column = 49 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 122 ; length = 1 line = 2 ; column = 50 ; value ='z'; }
{kind = TOKEN_COMMA; ; index = 123 ; length = 1 line = 2 ; column = 51 ; value =','; }
{kind = TOKEN_FLOATLITERAL; ; index = 125 ; length = 3 line = 2 ; column = 53 ; value ='1'; }
{kind = TOKEN_RIGHTPAREN; ; index = 128 ; length = 1 line = 2 ; column = 56 ; value =')'; }
{kind = TOKEN_SEMICOLON; ; index = 129 ; length = 1 line = 2 ; column = 57 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 132 ; length = 1 line = 3 ; column = 0 ; value ='}'; }
{kind = TOKEN_PIXEL; ; index = 137 ; length = 5 line = 5 ; column = 0 ; value ='pixel'; }
{kind = TOKEN_IDENTIFIER; ; index = 143 ; length = 7 line = 5 ; column = 6 ; value ='ps_main'; }
{kind = TOKEN_DOUBLECOLON; ; index = 151 ; length = 2 line = 5 ; column = 14 ; value ='::'; }
{kind = TOKEN_LEFTPAREN; ; index = 154 ; length = 1 line = 5 ; column = 17 ; value ='('; }
{kind = TOKEN_IDENTIFIER; ; index = 155 ; length = 8 line = 5 ; column = 18 ; value ='position'; }
{kind = TOKEN_COLON; ; index = 164 ; length = 1 line = 5 ; column = 27 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 166 ; length = 6 line = 5 ; column = 29 ; value ='float4'; }
{kind = TOKEN_AT; ; index = 173 ; length = 1 line = 5 ; column = 36 ; value ='@'; }
{kind = TOKEN_IDENTIFIER; ; index = 174 ; length = 11 line = 5 ; column = 37 ; value ='outposition'; }
{kind = TOKEN_RIGHTPAREN; ; index = 185 ; length = 1 line = 5 ; column = 48 ; value =')'; }
{kind = TOKEN_ARROW; ; index = 187 ; length = 2 line = 5 ; column = 50 ; value ='->'; }
{kind = TOKEN_IDENTIFIER; ; index = 190 ; length = 6 line = 5 ; column = 53 ; value ='float4'; }
{kind = TOKEN_AT; ; index = 197 ; length = 1 line = 5 ; column = 60 ; value ='@'; }
{kind = TOKEN_IDENTIFIER; ; index = 198 ; length = 6 line = 5 ; column = 61 ; value ='target'; }
{kind = TOKEN_LEFTBRACE; ; index = 205 ; length = 1 line = 5 ; column = 68 ; value ='{'; }
{kind = TOKEN_RETURN; ; index = 211 ; length = 6 line = 6 ; column = 2 ; value ='return'; }
{kind = TOKEN_IDENTIFIER; ; index = 218 ; length = 6 line = 6 ; column = 9 ; value ='float4'; }
{kind = TOKEN_LEFTPAREN; ; index = 224 ; length = 1 line = 6 ; column = 15 ; value ='('; }
{kind = TOKEN_FLOATLITERAL; ; index = 225 ; length = 3 line = 6 ; column = 16 ; value ='0.5'; }
{kind = TOKEN_COMMA; ; index = 228 ; length = 1 line = 6 ; column = 19 ; value =','; }
{kind = TOKEN_MINUS; ; index = 230 ; length = 1 line = 6 ; column = 21 ; value ='-'; }
{kind = TOKEN_INTLITERAL; ; index = 231 ; length = 1 line = 6 ; column = 22 ; value ='1'; }
{kind = TOKEN_COMMA; ; index = 232 ; length = 1 line = 6 ; column = 23 ; value =','; }
{kind = TOKEN_INTLITERAL; ; index = 234 ; length = 1 line = 6 ; column = 25 ; value ='0'; }
{kind = TOKEN_COMMA; ; index = 235 ; length = 1 line = 6 ; column = 26 ; value =','; }
{kind = TOKEN_INTLITERAL; ; index = 237 ; length = 1 line = 6 ; column = 28 ; value ='1'; }
{kind = TOKEN_RIGHTPAREN; ; index = 238 ; length = 1 line = 6 ; column = 29 ; value =')'; }
{kind = TOKEN_SEMICOLON; ; index = 239 ; length = 1 line = 6 ; column = 30 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 242 ; length = 1 line = 7 ; column = 0 ; value ='}'; }
{kind = TOKEN_EOF; ; index = 243 ; length = 0 line = 7 ; column = 1 ; value =''; }

View File

@@ -24,6 +24,7 @@ test/simple_struct_access.ink lex
test/struct_access_primitive_type.ink lex
test/struct_within_struct.ink lex
test/type_as_variable_name.ink lex
test/unary.ink lex
test/undeclared_function.ink lex
test/undeclared_symbol.ink lex
test/unknown_overload.ink lex

View File

@@ -1,4 +1,4 @@
test/field_without_type_specifier.inx:2,0: error: Expected type specifier after field name.
test/field_without_type_specifier.ink:2,0: error: Expected type specifier after field name.
x := 5.0;
^


8
test/parse/unary.golden Normal file
View File

@@ -0,0 +1,8 @@
(program
(fun vertex vs_vs_main -> float4 (@position)
[(:= position float3 (@position))]
(return (float4 position.x position.y position.z 1)))
(fun pixel ps_ps_main -> float4 (@target)
[(:= position float4 (@outposition))]
(return (float4 0.5 -1 0 1))))

View File

@@ -24,6 +24,7 @@ test/simple_struct_access.ink parse
test/struct_access_primitive_type.ink parse
test/struct_within_struct.ink parse
test/type_as_variable_name.ink parse
test/unary.ink parse
test/undeclared_function.ink parse
test/undeclared_symbol.ink parse
test/unknown_overload.ink parse

View File

@@ -1,8 +1,8 @@
test/functions_with_same_name.inx:2,0: error: Redeclaration of 'foo'
test/functions_with_same_name.ink:2,0: error: Redeclaration of 'foo'
 foo :: () {
^^^
test/functions_with_same_name.inx:1,0: info: Here is the first declaration of 'foo'
test/functions_with_same_name.ink:1,0: info: Here is the first declaration of 'foo'
 foo :: () {
^^^


View File

@@ -1,8 +1,8 @@
test/redeclared_variable.inx:3,0: error: Redeclaration of 'x'
test/redeclared_variable.ink:3,0: error: Redeclaration of 'x'
 x : float = 5.0
^
test/redeclared_variable.inx:2,0: info: Here is the first declaration of 'x'
test/redeclared_variable.ink:2,0: info: Here is the first declaration of 'x'
 x : float = 1.0
^


View File

@@ -1,4 +1,4 @@
test/struct_access_primitive_type.inx:3,0: error: Attempting to access a field on a primitive type 'int'.
test/struct_access_primitive_type.ink:3,0: error: Attempting to access a field on a primitive type 'int'.
x.d = 4;
^
declaration:

View File

@@ -1,4 +1,4 @@
test/type_as_variable_name.inx:2,0: error: Invalid variable name 'int'
test/type_as_variable_name.ink:2,0: error: Invalid variable name 'int'
 int : float = 4.0
^^^


10
test/semant/unary.golden Normal file
View File

@@ -0,0 +1,10 @@
scope (global) [
[pixel__ps_ps_main] : (position : float4) -> float4
[vertex__vs_vs_main] : (position : float3) -> float4
scope (vertex__vs_vs_main) [
[position] : float3
]
scope (pixel__ps_ps_main) [
[position] : float4
]
]

View File

@@ -1,4 +1,4 @@
test/undeclared_function.inx:2,0: error: Attempt to call undeclared function 'foo'.
test/undeclared_function.ink:2,0: error: Attempt to call undeclared function 'foo'.
 foo();
^^^

View File

@@ -1,4 +1,4 @@
test/undeclared_symbol.inx:2,10: error: Use of undeclared symbol 'f'
test/undeclared_symbol.ink:2,10: error: Use of undeclared symbol 'f'
 b : int = f;
^


View File

@@ -1,4 +1,4 @@
test/unknown_overload.inx:6,0: error: Procedure call did not match any of the possible overloads for 'foo'
test/unknown_overload.ink:6,0: error: Procedure call did not match any of the possible overloads for 'foo'
 found:
foo(v, v);
^^^
@@ -7,10 +7,10 @@
 foo(v, v);
^
 Possible overloads:
 foo :: (v1 : float3, v2 : float3) { (test/unknown_overload.inx:1)
 foo :: (v1 : float2, v2 : float2, v3 : float2) { (test/unknown_overload.inx:2)
 foo :: (v1 : float3, v2 : float3) { (test/unknown_overload.ink:1)
 foo :: (v1 : float2, v2 : float2, v3 : float2) { (test/unknown_overload.ink:2)
test/unknown_overload.inx:6,4: error: Type mismatch. Expected float3 got float
test/unknown_overload.ink:6,4: error: Type mismatch. Expected float3 got float
 found:
foo(v, v);
^
@@ -20,7 +20,7 @@
got:
v : float = 2.0
test/unknown_overload.inx:6,7: error: Type mismatch. Expected float3 got float
test/unknown_overload.ink:6,7: error: Type mismatch. Expected float3 got float
 found:
foo(v, v);
^

View File

@@ -1,15 +1,15 @@
test/wrong_argument_count.inx:5,19: error: Use of undeclared symbol 'w'
test/wrong_argument_count.ink:5,19: error: Use of undeclared symbol 'w'
 return x * y * z * w;
^
test/wrong_argument_count.inx:9,0: error: Procedure call did not match any of the possible overloads for 'foo'
test/wrong_argument_count.ink:9,0: error: Procedure call did not match any of the possible overloads for 'foo'
 found:
foo(2.0, 3.0);
^^^
 Possible overloads:
 foo :: (x : float, y : float, z : float) -> float { (test/wrong_argument_count.inx:1)
 foo :: (x : float, y : float, z : float) -> float { (test/wrong_argument_count.ink:1)
 Not enough arguments: Wanted 3, got 2.
 foo :: (x : float, y : float, z : float, w : float) -> float { (test/wrong_argument_count.inx:4)
 foo :: (x : float, y : float, z : float, w : float) -> float { (test/wrong_argument_count.ink:4)
 Not enough arguments: Wanted 4, got 2.

View File

@@ -1,4 +1,4 @@
test/wrong_multiply.inx:4,34: error: Type mismatch. Expected float got float2
test/wrong_multiply.ink:4,34: error: Type mismatch. Expected float got float2
 found:
result : float4 = float4(1.0, foo * res, 0.0, 1.0);
^

View File

@@ -1,4 +1,4 @@
test/wrong_type_for_function.inx:11,17: error: Procedure call did not match any of the possible overloads for 'float4'
test/wrong_type_for_function.ink:11,17: error: Procedure call did not match any of the possible overloads for 'float4'
 found:
color : float4 = float4(y, 1.0, 1.0, 1.0);
^^^^^^
@@ -7,9 +7,9 @@
 color : float4 = float4(y, 1.0, 1.0, 1.0);
^
 Possible overloads:
 foreign float4 :: (float, float, float, float) -> float4; (test/wrong_type_for_function.inx:78)
 foreign float4 :: (float, float, float, float) -> float4; (test/wrong_type_for_function.ink:78)
test/wrong_type_for_function.inx:11,24: error: Type mismatch. Expected float got float2
test/wrong_type_for_function.ink:11,24: error: Type mismatch. Expected float got float2
 found:
color : float4 = float4(y, 1.0, 1.0, 1.0);
^

View File

@@ -21,6 +21,7 @@ test/simple_struct_access.ink semant
test/struct_access_primitive_type.ink semant
test/struct_within_struct.ink semant
test/type_as_variable_name.ink semant
test/unary.ink semant
test/undeclared_function.ink semant
test/undeclared_symbol.ink semant
test/unknown_overload.ink semant

7
test/unary.ink Normal file
View File

@@ -0,0 +1,7 @@
vertex vs_main :: (position : float3 @position) -> float4 @position {
return float4(position.x, position.y, position.z, 1.0);
}
pixel ps_main :: (position : float4 @outposition) -> float4 @target {
return float4(0.5, -1, 0, 1);
}