Compare commits

3 Commits

54 changed files with 657 additions and 229 deletions

31
AST.jai
View File

@@ -12,9 +12,7 @@ AST_Kind :: enum {
// Directives // Directives
If_Directive; If_Directive;
// Hint; Access;
// Type;
// Operator;
Call; Call;
Struct; Struct;
If; If;
@@ -257,15 +255,16 @@ pretty_print_binary :: (node : *AST_Node, indentation : int, builder : *String_B
if !skip_indent { if !skip_indent {
indent(builder, indentation); indent(builder, indentation);
} }
append(builder, "(");
is_array_access := false;
if node.token.kind == .TOKEN_LEFTBRACKET { if node.token.kind == .TOKEN_LEFTBRACKET {
print_to_builder(builder, "[]"); pretty_print_node(node.children[0], 0, builder);
append(builder, "[");
pretty_print_node(node.children[1], 0, builder);
append(builder, "]");
} else { } else {
append(builder, "(");
op := node.token; op := node.token;
print_to_builder(builder, op_to_string(op)); print_to_builder(builder, op_to_string(op));
}
append(builder, " "); append(builder, " ");
pretty_print_node(node.children[0], 0, builder); pretty_print_node(node.children[0], 0, builder);
@@ -274,6 +273,19 @@ pretty_print_binary :: (node : *AST_Node, indentation : int, builder : *String_B
append(builder, ")"); append(builder, ")");
} }
}
pretty_print_access :: (node : *AST_Node, indentation : int, builder : *String_Builder, skip_indent := false) {
if !skip_indent {
indent(builder, indentation);
}
pretty_print_node(node.children[0], 0, builder);
append(builder, ".");
pretty_print_node(node.children[1], 0, builder);
}
pretty_print_unary :: (node : *AST_Node, indentation : int, builder : *String_Builder, skip_indent := false) { pretty_print_unary :: (node : *AST_Node, indentation : int, builder : *String_Builder, skip_indent := false) {
if !skip_indent { if !skip_indent {
indent(builder, indentation); indent(builder, indentation);
@@ -402,6 +414,9 @@ pretty_print_node :: (node : *AST_Node, indentation : int, builder : *String_Bui
case .Binary; { case .Binary; {
pretty_print_binary(node, indentation, builder, skip_indent); pretty_print_binary(node, indentation, builder, skip_indent);
} }
case .Access; {
pretty_print_access(node, indentation, builder, skip_indent);
}
case .Unary; { case .Unary; {
pretty_print_unary(node, indentation, builder, skip_indent); pretty_print_unary(node, indentation, builder, skip_indent);
} }

200
Check.jai
View File

@@ -5,9 +5,11 @@
///////////////////////////////////// /////////////////////////////////////
//~ nbr: Error reporting TODOs //~ nbr: Error reporting TODOs
// //
// [ ] Add a sentinel variable that works for from_handle
// [ ] Add and error for using keywords as names, or rename the dx11 keywords in the resulting hlsl shader. // [ ] Add and error for using keywords as names, or rename the dx11 keywords in the resulting hlsl shader.
// [ ] Add missing scope in for loop for loop iterator // [ ] Add missing scope in for loop for loop iterator
// [ ] Maybe we remove the resource index on type variables, seems like we don't need it there. // [ ] Add swizzling
// [ ] Add temp assignment fail check: (a + b).x = float2(0, 0);
// [x] Improve error reporting on mismatched overloads when types don't match, but arity does. // [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.
@@ -154,6 +156,8 @@ Checker :: struct {
ctx : *Compiler_Context; ctx : *Compiler_Context;
checking_lvalue : bool;
current_buffer_index : u32 = 0; current_buffer_index : u32 = 0;
current_sampler_index : u32 = 0; current_sampler_index : u32 = 0;
current_texture_index : u32 = 0; current_texture_index : u32 = 0;
@@ -418,6 +422,43 @@ Error: Undeclared identifier 'name'.
record_error(checker, message, node.source_location, false); record_error(checker, message, node.source_location, false);
} }
cannot_assign_to_lvalue :: (checker : *Checker, node : *AST_Node) {
/*
Cannot assign to an lvalue.
(a + b).x = 2.0;
*/
builder : String_Builder;
init_string_builder(*builder,, temp);
append(*builder, "Cannot assign to an lvalue.\n");
cyan(*builder);
indent(*builder, 1);
location := node.source_location;
begin : Token = node.token;
begin.index -= begin.column;
begin.length += begin.column;
begin.source -= begin.column;
begin.column = 0;
location.begin = begin;
print("%\n", location.main_token.kind);
print_to_builder(*builder, "%\n", print_from_source_location(checker.ctx, location));
// print_to_builder(*builder, "%\n", print_from_source_location(checker.ctx, node.source_location));
indent(*builder, 1);
print_token_pointer(*builder, location.begin);
newline(*builder);
newline(*builder);
message := builder_to_string(*builder);
record_error(checker, message, node.source_location, false);
}
field_not_defined_on_struct :: (checker : *Checker, node : *AST_Node, struct_symbol : *Defined_Symbol) { field_not_defined_on_struct :: (checker : *Checker, node : *AST_Node, struct_symbol : *Defined_Symbol) {
/* /*
Field '%' is not defined in struct '%'. Field '%' is not defined in struct '%'.
@@ -472,12 +513,10 @@ Attempting to access a field on a primitive type '%'.
print_to_builder(*builder, "%\n", print_from_source_location(checker.ctx, node.source_location)); print_to_builder(*builder, "%\n", print_from_source_location(checker.ctx, node.source_location));
indent(*builder, 1); indent(*builder, 1);
node_variable := from_handle(checker, node.type_variable); // for 0..variable.source_node.name.count - 1 {
// append(*builder, " ");
for 0..node.name.count - 1 { // }
append(*builder, " "); print_token_pointer(*builder, node.source_location.main_token);
}
print_token_pointer(*builder, node.source_location.begin);
append(*builder, "\n"); append(*builder, "\n");
@@ -1071,7 +1110,7 @@ declare_cbuffer :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handl
var.type = .CBuffer; var.type = .CBuffer;
var.resource_index = checker.current_buffer_index; var.resource_index = checker.current_buffer_index;
checker.current_buffer_index += 1; checker.current_buffer_index += 1;
array_add(*checker.ctx.constant_buffers, type_var); array_add(*checker.ctx.typed_buffers, type_var);
return type_var; return type_var;
} }
@@ -1080,12 +1119,34 @@ declare_buffer :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle
variable.type = .Buffer; variable.type = .Buffer;
variable.source_kind = .Declaration; variable.source_kind = .Declaration;
variable.name = node.name; variable.name = node.name;
variable.source_node = node;
variable.element_type = declare_struct(checker, node); // Won't work entirely like this. At least we're going to need some access changes find_result := find_symbol(checker, node.name, checker.current_scope);
if !find_result {
symbol : Defined_Symbol;
symbol.name = node.name;
symbol.source_node = node;
symbol.type_variable = handle;
add_symbol_to_scope(checker.state, *checker.ctx.scope_stack, checker.current_scope, node.name, symbol);
} else {
symbol_redeclaration(checker, node, find_result);
return 0;
}
variable.resource_index = checker.current_buffer_index; buffer_struct_name := sprint("__buffer_substruct__%_%", random_get(), node.name);
checker.current_buffer_index += 1;
array_add(*checker.ctx.buffers, handle); variable.element_type = declare_struct(checker, node, buffer_struct_name);
variable.resource_index = checker.current_texture_index;
element := from_handle(checker, variable.element_type);
scope := get_scope(checker, element.scope);
scope.builtin = true;
variable.scope = element.scope;
checker.current_texture_index += 1;
node.type_variable = handle;
array_add(*checker.ctx.typed_buffers, handle);
return handle; return handle;
} }
@@ -1139,7 +1200,7 @@ declare_function :: (checker : *Checker, node : *AST_Node, builtin : bool = fals
symbol.source_node = node; symbol.source_node = node;
symbol.type_variable = 0; symbol.type_variable = 0;
symbol.functions.allocator = get_current_scope(checker).allocator; symbol.functions.allocator = get_current_scope(checker).allocator;
array_reserve(*symbol.functions, 32); array_reserve(*symbol.functions, 4);
array_add(*symbol.functions, function); array_add(*symbol.functions, function);
add_symbol_to_scope(checker.state, *checker.ctx.scope_stack, checker.current_scope, name_to_check, symbol); add_symbol_to_scope(checker.state, *checker.ctx.scope_stack, checker.current_scope, name_to_check, symbol);
@@ -1202,7 +1263,8 @@ declare_function :: (checker : *Checker, node : *AST_Node, builtin : bool = fals
variable.scope = scope_handle; variable.scope = scope_handle;
} }
for child : node.children { for i : 0..node.children.count - 1 {
child := node.children[i];
if child.kind == .FieldList { if child.kind == .FieldList {
for field : child.children { for field : child.children {
type_var := check_node(checker, field); type_var := check_node(checker, field);
@@ -1281,43 +1343,13 @@ check_function :: (checker : *Checker, node : *AST_Node) {
} }
} }
check_variable :: (checker : *Checker, node : *AST_Node, struct_field_parent : *AST_Node = null) -> Type_Variable_Handle { check_variable :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
find_result := find_symbol(checker, node.name, checker.current_scope); find_result := find_symbol(checker, node.name, checker.current_scope);
// x : int;
// x.d = 5;
if find_result { if find_result {
node.type_variable = find_result.type_variable; node.type_variable = find_result.type_variable;
variable := from_handle(checker, find_result.type_variable); variable := from_handle(checker, find_result.type_variable);
variable.struct_field_parent = struct_field_parent;
if get_scope(checker, checker.current_scope).kind == .Struct {
variable.scope = checker.current_scope;
}
if node.children.count > 0 {
if variable.type != .Struct && variable.type != .CBuffer && variable.type != .Buffer {
field_access_on_primitive_type(checker, node, find_result.type_variable);
return 0;
} else if variable.type == .Array {
} else {
lookup_name : string = variable.typename;
struct_symbol := find_symbol(checker, lookup_name, checker.current_scope);
type_variable := from_handle(checker, struct_symbol.type_variable);
previous_scope := use_scope(checker, type_variable.scope);
child := node.children[0];
var := find_symbol(checker, child.name, type_variable.scope);
if var == null {
field_not_defined_on_struct(checker, child, struct_symbol);
return 0;
}
access := check_variable(checker, child, node);
use_scope(checker, previous_scope);
return access;
}
}
return find_result.type_variable; return find_result.type_variable;
} }
@@ -1573,8 +1605,46 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
return handle; return handle;
} }
case .Access; {
lhs_handle := check_node(checker, node.children[0]);
if lhs_handle == 0 {
return 0;
}
lhs_variable := from_handle(checker, lhs_handle);
if lhs_variable.type != .Struct && lhs_variable.type != .CBuffer {
field_access_on_primitive_type(checker, node.children[0], lhs_handle);
return 0;
}
lookup_name := lhs_variable.typename;
struct_symbol := find_symbol(checker, lookup_name, checker.current_scope);
type_variable := from_handle(checker, struct_symbol.type_variable);
previous_scope := use_scope(checker, type_variable.scope);
member := node.children[1];
var := find_symbol(checker, member.name, type_variable.scope);
if var == null {
field_not_defined_on_struct(checker, member, struct_symbol);
return 0;
}
access := check_node(checker, member);
use_scope(checker, previous_scope);
return access;
}
case .Binary; { case .Binary; {
if checker.checking_lvalue {
cannot_assign_to_lvalue(checker, node.parent.parent);
return 0;
}
prev_checking_lvalue := checker.checking_lvalue;
if node.token.kind == .TOKEN_ASSIGN {
checker.checking_lvalue = true;
}
lhs_var := check_node(checker, node.children[0]); lhs_var := check_node(checker, node.children[0]);
checker.checking_lvalue = prev_checking_lvalue;
if lhs_var == 0 { if lhs_var == 0 {
return 0; return 0;
} }
@@ -1587,7 +1657,14 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
lhs_type := from_handle(checker, lhs_var); lhs_type := from_handle(checker, lhs_var);
rhs_type := from_handle(checker, rhs_var); rhs_type := from_handle(checker, rhs_var);
if lhs_type.type == .Array {
element := from_handle(checker, lhs_type.element_type);
variable.type = element.type;
variable.typename = element.typename;
} else {
variable.type = lhs_type.type; variable.type = lhs_type.type;
}
variable.typename = lhs_type.typename; variable.typename = lhs_type.typename;
variable.scope = lhs_type.scope; variable.scope = lhs_type.scope;
variable.source_node = node; variable.source_node = node;
@@ -1621,11 +1698,18 @@ check_node :: (checker : *Checker, node : *AST_Node) -> Type_Variable_Handle {
} }
} }
case .TOKEN_ASSIGN; { case .TOKEN_ASSIGN; {
if lhs_type.type == .Array {
if !types_compatible(checker, lhs_type.element_type, rhs_var) {
type_mismatch(checker, node.parent, node.children[1], lhs_var, rhs_var);
return 0;
}
} else {
if !types_compatible(checker, lhs_var, rhs_var) { if !types_compatible(checker, lhs_var, rhs_var) {
type_mismatch(checker, node.parent, node.children[1], lhs_var, rhs_var); type_mismatch(checker, node.parent, node.children[1], lhs_var, rhs_var);
return 0; return 0;
} }
} }
}
case .TOKEN_GREATER; #through; case .TOKEN_GREATER; #through;
case .TOKEN_GREATEREQUALS; #through; case .TOKEN_GREATEREQUALS; #through;
case .TOKEN_LESS; #through; case .TOKEN_LESS; #through;
@@ -1746,7 +1830,17 @@ is_valid_define :: (checker : *Checker, def : string) -> bool {
} }
check_env_expression :: (checker : *Checker, expr : *AST_Node, directive : *AST_Node) -> bool { check_env_expression :: (checker : *Checker, expr : *AST_Node, directive : *AST_Node) -> bool {
if expr.kind == .Binary { if expr.kind == .Access {
lhs := expr.children[0];
if lhs.kind == .Variable && lhs.name == "Env" {
rhs := expr.children[1];
return is_valid_define(checker, rhs.name);
} else {
return check_env_expression(checker, lhs, directive);
}
}
else if expr.kind == .Binary {
lhs := expr.children[0]; lhs := expr.children[0];
rhs := expr.children[1]; rhs := expr.children[1];
@@ -1759,6 +1853,7 @@ check_env_expression :: (checker : *Checker, expr : *AST_Node, directive : *AST_
return lhs_valid && rhs_valid; return lhs_valid && rhs_valid;
} }
} else if expr.kind == .Variable { } else if expr.kind == .Variable {
assert(false, "");
if expr.name == "Env" { if expr.name == "Env" {
child := expr.children[0]; // The variable in the environment child := expr.children[0]; // The variable in the environment
@@ -1883,8 +1978,6 @@ types_compatible :: (checker : *Checker, lhs : Type_Variable_Handle, rhs : Type_
return rhs_var.type == lhs_var.type; return rhs_var.type == lhs_var.type;
} }
case .Struct; { case .Struct; {
lhs_node := lhs_var.source_node;
rhs_node := rhs_var.source_node;
if rhs_var.type != .Struct && !param_matching { if rhs_var.type != .Struct && !param_matching {
if lhs_var.typename == { if lhs_var.typename == {
case "float2"; #through; case "float2"; #through;
@@ -2451,7 +2544,13 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, type_variable, 1); pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, type_variable, 1);
append(builder, "\n"); append(builder, "\n");
} }
case .Buffer; {
element := from_handle(variables, type_variable.element_type);
pretty_print_struct(ctx, *scope_stack, current_scope, variables, builder, key, element, 1);
append(builder, "\n");
}
case .Struct; { case .Struct; {
if type_variable.source_node.kind != .Buffer {
if type_variable.typename.count > 0 && !type_variable.builtin && (type_variable.source_kind != .Declaration || type_variable.source_node.kind != .Struct) { if type_variable.typename.count > 0 && !type_variable.builtin && (type_variable.source_kind != .Declaration || type_variable.source_node.kind != .Struct) {
indent(builder, indentation + 1); indent(builder, indentation + 1);
print_key(*scope_stack, current_scope, builder, key); print_key(*scope_stack, current_scope, builder, key);
@@ -2461,6 +2560,7 @@ pretty_print_scope :: (ctx : *Compiler_Context, current_scope : Scope_Handle, sc
append(builder, "\n"); append(builder, "\n");
} }
} }
}
case; { case; {
indent(builder, indentation + 1); indent(builder, indentation + 1);
print_key(*scope_stack, current_scope, builder, key); print_key(*scope_stack, current_scope, builder, key);
@@ -2501,6 +2601,9 @@ print_type_variable :: (ctx : *Compiler_Context, builder : *String_Builder, vari
} }
print_to_builder(builder, "%", node.name); print_to_builder(builder, "%", node.name);
}
case .Access; {
} }
case .Binary; { case .Binary; {
left_most := node.children[0]; left_most := node.children[0];
@@ -2582,3 +2685,4 @@ pretty_print_symbol_table :: (ctx : *Compiler_Context, allocator : Allocator) ->
#import "ncore"; #import "ncore";
#import "Hash_Table"; #import "Hash_Table";
#import "String"; #import "String";
#import "Random";

View File

@@ -146,13 +146,20 @@ emit_field :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
} }
emit_block :: (state : *Codegen_State, node : *AST_Node, indentation : int) { emit_block :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
previous_scope := state.current_scope;
for statement : node.children { for statement : node.children {
if statement.type_variable {
state.current_scope = from_handle(state.ctx.type_variables, statement.type_variable).scope;
}
emit_node(state, statement, indentation); emit_node(state, statement, indentation);
if it_index < node.children.count { if it_index < node.children.count {
append(*state.builder, "\n"); append(*state.builder, "\n");
} }
} }
state.current_scope = previous_scope;
} }
emit_call :: (state : *Codegen_State, node : *AST_Node, indentation : int) { emit_call :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
@@ -379,12 +386,25 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
emit_node(state, node.children[0], 0); emit_node(state, node.children[0], 0);
} }
} }
case .Access; {
indent(*state.builder, indentation);
lhs := node.children[0];
rhs := node.children[1];
emit_node(state, lhs, 0);
print_to_builder(*state.builder, "%.", node.name);
emit_node(state, rhs, 0);
}
case .Binary; { case .Binary; {
indent(*state.builder, indentation); indent(*state.builder, indentation);
if node.token.kind != .TOKEN_ASSIGN && node.token.kind != .TOKEN_LEFTBRACKET { if node.token.kind != .TOKEN_ASSIGN && node.token.kind != .TOKEN_LEFTBRACKET {
if (node.parent.kind == .Binary && node.parent.token.kind != .TOKEN_ASSIGN) || node.parent.kind == .Access {
append(*state.builder, "("); append(*state.builder, "(");
} }
}
lhs := node.children[0]; lhs := node.children[0];
rhs := node.children[1]; rhs := node.children[1];
@@ -402,12 +422,12 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
emit_node(state, rhs, 0); emit_node(state, rhs, 0);
} }
if node.token.kind != .TOKEN_ASSIGN && node.token.kind != .TOKEN_LEFTBRACKET { if node.token.kind != .TOKEN_ASSIGN && node.token.kind != .TOKEN_LEFTBRACKET {
if (node.parent.kind == .Binary && node.parent.token.kind != .TOKEN_ASSIGN) || node.parent.kind == .Access {
append(*state.builder, ")"); append(*state.builder, ")");
} }
} }
}
case .Unary; { case .Unary; {
indent(*state.builder, indentation); indent(*state.builder, indentation);
@@ -455,7 +475,9 @@ emit_node :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
append(*state.builder, "if "); append(*state.builder, "if ");
cond := node.children[0]; cond := node.children[0];
append(*state.builder, "(");
emit_node(state, cond, 0); emit_node(state, cond, 0);
append(*state.builder, ")");
body := node.children[1]; body := node.children[1];
append(*state.builder, "\n"); append(*state.builder, "\n");
@@ -502,8 +524,13 @@ emit_field_list :: (state : *Codegen_State, field_list : *AST_Node, indentation
} }
} }
emit_struct :: (state : *Codegen_State, node : *AST_Node, indentation : int) { emit_struct :: (state : *Codegen_State, node : *AST_Node, indentation : int, name : string = "") {
if name.count > 0 {
print_to_builder(*state.builder, "struct %", name);
} else {
print_to_builder(*state.builder, "struct %", node.name); print_to_builder(*state.builder, "struct %", node.name);
}
current_scope := state.current_scope; current_scope := state.current_scope;
state.current_scope = from_handle(state.ctx.type_variables, node.type_variable).scope; state.current_scope = from_handle(state.ctx.type_variables, node.type_variable).scope;
@@ -543,6 +570,15 @@ emit_cbuffer :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
state.current_scope = current_scope; state.current_scope = current_scope;
} }
emit_buffer :: (state : *Codegen_State, node : *AST_Node, indentation : int) {
variable := from_handle(state.ctx.type_variables, node.type_variable);
element := from_handle(state.ctx.type_variables, variable.element_type);
emit_struct(state, node, indentation, element.typename);
print_to_builder(*state.builder, "StructuredBuffer<%> % : register(t%);\n\n", element.typename, variable.name, variable.resource_index);
}
emit_declaration :: (state : *Codegen_State, node : *AST_Node) { emit_declaration :: (state : *Codegen_State, node : *AST_Node) {
if node.kind == { if node.kind == {
case .Function; { case .Function; {
@@ -551,6 +587,9 @@ emit_declaration :: (state : *Codegen_State, node : *AST_Node) {
case .CBuffer; { case .CBuffer; {
emit_cbuffer(state, node, 0); emit_cbuffer(state, node, 0);
} }
case .Buffer; {
emit_buffer(state, node, 0);
}
case .Struct; { case .Struct; {
emit_struct(state, node, 0); emit_struct(state, node, 0);
} }

19
Ink.jai
View File

@@ -227,11 +227,18 @@ run_compile_test :: (path : string, output_type : Output_Type = 0) -> Result, Co
print_to_builder(*sb, "[pixel entry point] - %\n", ctx.pixel_entry_point.name); print_to_builder(*sb, "[pixel entry point] - %\n", ctx.pixel_entry_point.name);
} }
for cb : ctx.cbuffers { for buf : ctx.buffers {
print_to_builder(*sb, "[constant_buffer] - % - %", cb.name, cb.buffer_index); if buf.kind == {
case .Constant; {
print_to_builder(*sb, "[constant_buffer] - % - %", buf.name, buf.buffer_index);
if cb.hints.count > 0 { }
for hint : cb.hints { case .Structured; {
print_to_builder(*sb, "[buffer] - % - %", buf.name, buf.buffer_index);
}
if buf.hints.count > 0 {
for hint : buf.hints {
print_to_builder(*sb, " (@%)", hint.custom_hint_name); print_to_builder(*sb, " (@%)", hint.custom_hint_name);
} }
} }
@@ -239,7 +246,7 @@ run_compile_test :: (path : string, output_type : Output_Type = 0) -> Result, Co
append(*sb, "\n"); append(*sb, "\n");
indent(*sb, 1); indent(*sb, 1);
for field : cb.fields { for field : buf.fields {
append(*sb, "[field] - "); append(*sb, "[field] - ");
pretty_print_field(*sb, *field); pretty_print_field(*sb, *field);
append(*sb, "\n"); append(*sb, "\n");
@@ -247,6 +254,8 @@ run_compile_test :: (path : string, output_type : Output_Type = 0) -> Result, Co
} }
} }
}
result.info_text = builder_to_string(*sb); result.info_text = builder_to_string(*sb);
} }

View File

@@ -217,11 +217,11 @@ identifier_kind :: (using lexer : *Lexer) -> Token_Kind {
identifier.count = length; identifier.count = length;
if identifier == "bool" return .TOKEN_BOOL; if identifier == "bool" return .TOKEN_BOOL;
if identifier == "buffer" return .TOKEN_BUFFER; if identifier == "Buffer" return .TOKEN_BUFFER;
if identifier == "case" return .TOKEN_CASE; if identifier == "case" return .TOKEN_CASE;
if identifier == "columnmajor" return .TOKEN_COLUMNMAJOR; if identifier == "columnmajor" return .TOKEN_COLUMNMAJOR;
if identifier == "const" return .TOKEN_CONST; if identifier == "const" return .TOKEN_CONST;
if identifier == "constant_buffer" return .TOKEN_CONSTANT_BUFFER; if identifier == "Constant_Buffer" return .TOKEN_CONSTANT_BUFFER;
if identifier == "continue" return .TOKEN_CONTINUE; if identifier == "continue" return .TOKEN_CONTINUE;
if identifier == "default" return .TOKEN_DEFAULT; if identifier == "default" return .TOKEN_DEFAULT;
if identifier == "directive" return .TOKEN_DIRECTIVE; if identifier == "directive" return .TOKEN_DIRECTIVE;

View File

@@ -1,13 +1,3 @@
#import "Flat_Pool";
// #load "qpwodkqopwkd.jai";
/**
* TODO:
* if parsing
* for/while loop parsing
**/
//////////////////////////// ////////////////////////////
//@nb - Parse_state state //@nb - Parse_state state
Parse_State :: struct { Parse_State :: struct {
@@ -19,15 +9,6 @@ Parse_State :: struct {
ctx : *Compiler_Context; ctx : *Compiler_Context;
} }
////////////////////////////
//@nb - Result and error handling
Parse_Error_Kind :: enum {
Parse_Error_Type_Missing;
Parse_Error_Expected_Expression;
Parse_Error_Empty_Block;
Parse_Error_Unexpected_Token;
}
//////////////////////////// ////////////////////////////
//@nb - Parsing helper types //@nb - Parsing helper types
Separator_Type :: enum { Separator_Type :: enum {
@@ -818,49 +799,6 @@ directive :: (state : *Parse_State) -> *AST_Node {
if_directive.source_location = source_location; if_directive.source_location = source_location;
return if_directive; return if_directive;
} else if state.current.ident_value == "load" {
advance(state);
if check(state, .TOKEN_STRING) {
// path_tok := state.current;
// path := path_tok.string_value;
// advance(state);
// result : Compiler_Context;
// ctx.allocator = state.ctx.allocator;
// ctx.environment = state.ctx.environment;
// ctx.file = make_file(*result, path);
// if ctx.file.source.count == 0 {
// unable_to_open_file(state, path, path_tok);
// advance_to_sync_point(state);
// advance(state);
// return null;
// }
// consume(state, .TOKEN_SEMICOLON, "Expected ';' after #load directive");
// lex(*result);
// count := state.ctx.tokens..count;
// current_idx := state.current_token_index;
// result_count := ctx.tokens..count;
// // state.ctx.tokens..count -= 1;
// array_resize(*state.ctx.tokens., count + result_count - 1);
// memcpy(*state.ctx.tokens[current_idx + result_count - 1], *state.ctx.tokens[current_idx], size_of(Token) * (count - current_idx));
// for *tok : ctx.tokens. {
// if tok.kind == .TOKEN_EOF {
// break;
// }
// tok.builtin = true;
// state.ctx.tokens[it_index] = tok.*;
// }
}
} }
return null; return null;
@@ -898,34 +836,31 @@ dot :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
source_location : Source_Range; source_location : Source_Range;
source_location.begin = left.source_location.begin; source_location.begin = left.source_location.begin;
source_location.main_token = identifier;
access := make_node(parse_state, .Access);
variable := make_node(parse_state, .Variable);
variable.name = identifier.ident_value;
add_child(access, left);
add_child(access, variable);
if check_any(parse_state, .TOKEN_ASSIGN, .TOKEN_MINUSEQUALS, .TOKEN_PLUSEQUALS, .TOKEN_DIVEQUALS, .TOKEN_MODEQUALS, .TOKEN_TIMESEQUALS) { if check_any(parse_state, .TOKEN_ASSIGN, .TOKEN_MINUSEQUALS, .TOKEN_PLUSEQUALS, .TOKEN_DIVEQUALS, .TOKEN_MODEQUALS, .TOKEN_TIMESEQUALS) {
advance(parse_state); advance(parse_state);
variable := make_node(parse_state, .Variable); access.source_location = generate_source_location_from_token(parse_state, identifier);
variable.source_location = generate_source_location_from_token(parse_state, identifier);
variable.name = identifier.ident_value;
add_child(left, variable);
node := make_node(parse_state, .Binary); node := make_node(parse_state, .Binary);
node.token = parse_state.previous; node.token = parse_state.previous;
add_child(node, left); node.source_location = generate_source_location_from_token(parse_state, node.token);
add_child(node, access);
add_child(node, expression(parse_state)); add_child(node, expression(parse_state));
return node; return node;
} }
variable := make_node(parse_state, .Variable);
variable.name = identifier.ident_value;
if check(parse_state, .TOKEN_DOT) { source_location.end = parse_state.current;
advance(parse_state); access.source_location = source_location;
dot(parse_state, variable); return access;
}
add_child(left, variable);
source_location.end = parse_state.previous;
variable.source_location = source_location;
return left;
} }
integer :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node { integer :: (parse_state : *Parse_State, left : *AST_Node) -> *AST_Node {
@@ -1486,8 +1421,6 @@ declaration :: (parse_state : *Parse_State) -> *AST_Node {
consume(parse_state, .TOKEN_DOUBLECOLON, "Expect '::' after pixel entry point declaration."); consume(parse_state, .TOKEN_DOUBLECOLON, "Expect '::' after pixel entry point declaration.");
decl_node = function_declaration(parse_state, identifier, .Pixel); decl_node = function_declaration(parse_state, identifier, .Pixel);
} else if check(parse_state, .TOKEN_LEFTPAREN) {
decl_node = call(parse_state, null);
} else if check(parse_state, .TOKEN_DIRECTIVE) { } else if check(parse_state, .TOKEN_DIRECTIVE) {
decl_node = directive(parse_state); decl_node = directive(parse_state);
skip_statement = true; skip_statement = true;
@@ -1557,4 +1490,4 @@ parse :: (ctx : *Compiler_Context, allocator := temp) {
} }
} }
#load "AST.jai"; #load "ast.jai";

View File

@@ -13,7 +13,7 @@ build :: () {
} }
EXECUTABLE_NAME :: "ink"; EXECUTABLE_NAME :: "ink";
MAIN_FILE :: "Ink.jai"; MAIN_FILE :: "ink.jai";
options := get_build_options(w); options := get_build_options(w);

View File

@@ -1,8 +1,8 @@
#load "Lexing.jai"; #load "lexing.jai";
#load "Error.jai"; #load "error.jai";
#load "Parsing.jai"; #load "parsing.jai";
#load "Check.jai"; #load "check.jai";
#load "Codegen.jai"; #load "codegen.jai";
#import "File_Utilities"; #import "File_Utilities";
@@ -128,7 +128,13 @@ Entry_Point :: struct {
return_value : Field; return_value : Field;
} }
Constant_Buffer :: struct { Buffer_Kind :: enum {
Constant;
Structured;
}
Buffer :: struct {
kind : Buffer_Kind;
name : string; name : string;
fields : Static_Array(Field, 16); fields : Static_Array(Field, 16);
@@ -154,8 +160,8 @@ Compiler_Context :: struct {
codegen_result_text : string; codegen_result_text : string;
constant_buffers : Static_Array(Type_Variable_Handle, 16); typed_buffers : Static_Array(Type_Variable_Handle, 32);
buffers : Static_Array(Type_Variable_Handle, 16); // structured_buffers : Static_Array(Type_Variable_Handle, 16);
scope_stack : Scope_Stack; scope_stack : Scope_Stack;
type_variables : [..]Type_Variable; type_variables : [..]Type_Variable;
@@ -172,9 +178,9 @@ Compiler_Context :: struct {
return_value : Field; return_value : Field;
} }
max_constant_buffers :: 16; max_buffers :: 32;
cbuffers : Static_Array(Constant_Buffer, max_constant_buffers); buffers : Static_Array(Buffer, max_buffers);
had_error : bool; had_error : bool;
messages : [..]Compiler_Message; messages : [..]Compiler_Message;
@@ -403,6 +409,37 @@ type_variable_to_field :: (ctx : *Compiler_Context, variable : Type_Variable_Han
return type_variable_to_field(ctx, from_handle(ctx.type_variables, variable)); return type_variable_to_field(ctx, from_handle(ctx.type_variables, variable));
} }
generate_buffer :: (ctx : *Compiler_Context, type_handle : Type_Variable_Handle, buffers : *Static_Array) {
variable := from_handle(ctx.type_variables, type_handle);
buffer := array_add(buffers);
if variable.type == {
case .CBuffer; {
buffer.kind = .Constant;
}
case .Buffer; {
buffer.kind = .Structured;
}
}
buffer.name = variable.name;
for i : 0..variable.children.count - 1 {
child := variable.children[i];
field : Field = type_variable_to_field(ctx, from_handle(ctx.type_variables, child));
array_add(*buffer.fields, field);
}
buffer.buffer_index = variable.resource_index;
for hint : variable.source_node.hint_tokens {
field_hint : Field_Hint;
field_hint.custom_hint_name = hint.ident_value;
field_hint.kind = .Custom;
array_add(*buffer.hints, field_hint);
}
}
generate_output_data :: (ctx : *Compiler_Context) { generate_output_data :: (ctx : *Compiler_Context) {
if ctx.had_error { if ctx.had_error {
return; return;
@@ -427,26 +464,8 @@ generate_output_data :: (ctx : *Compiler_Context) {
} }
} }
for buffer_variable : ctx.constant_buffers { for buffer_variable : ctx.typed_buffers {
variable := from_handle(ctx.type_variables, buffer_variable); generate_buffer(ctx, buffer_variable, *ctx.buffers);
cb := array_add(*ctx.cbuffers);
cb.name = variable.name;
for i : 0..variable.children.count - 1 {
child := variable.children[i];
field : Field = type_variable_to_field(ctx, from_handle(ctx.type_variables, child));
array_add(*cb.fields, field);
}
cb.buffer_index = variable.resource_index;
for hint : variable.source_node.hint_tokens {
field_hint : Field_Hint;
field_hint.custom_hint_name = hint.ident_value;
field_hint.kind = .Custom;
array_add(*cb.hints, field_hint);
}
} }
if ctx.pixel_entry_point.node { if ctx.pixel_entry_point.node {

View File

@@ -0,0 +1,4 @@
vertex main :: () {
v : float2;
v.x = (2.0 + ((4.0 - 2.0) * 1.5)) * 3.0;
}

View File

@@ -1,5 +1,6 @@
vertex main :: () -> float4 @position { vertex main :: () -> float4 @position {
arr : [16].float4; arr : [16].float4;
// arr[0] = float4(1,1,1); arr[0] = float4(1, 1, 1, 1);
return arr[0]; pos := arr[1];
return pos;
} }

View File

@@ -0,0 +1,5 @@
vertex main :: () {
a : float2;
b : float2;
(a + b).x = 2.0;
}

View File

@@ -0,0 +1,10 @@
P :: struct {
v : float2;
}
vertex main :: () {
p : P;
p.v.x.y = 2.0;
// v : float2;
// v.x.y.z = 2.0;
}

View File

@@ -1,4 +1,4 @@
properties :: constant_buffer @properties { properties :: Constant_Buffer @properties {
color : float4; color : float4;
} }

View File

@@ -1,8 +1,8 @@
property_buffer :: buffer { property_buffer :: Buffer {
color : float4; color : float4;
} }
cbuffer :: constant_buffer { const_buffer :: Constant_Buffer {
color : float4; color : float4;
} }

View File

@@ -0,0 +1,6 @@
scope (global) [
[vertex__vs_main] : ()
scope (vertex__vs_main) [
[v] : float2
]
]

7
test/check/arrays.golden Normal file
View File

@@ -0,0 +1,7 @@
scope (global) [
[vertex__vs_main] : () -> float4
scope (vertex__vs_main) [
[pos] : float4
[arr] : [16].float4
]
]

View File

@@ -0,0 +1,6 @@
test/bad_double_access.ink:7,4: error: Attempting to access a field on a primitive type 'float'.
p.v.x.
^
declaration:
x: float


View File

@@ -0,0 +1,10 @@
scope (global) [
[vertex__vs_main] : ()
[p] : {v : float2}
scope (p) [
[v] : float2
]
scope (vertex__vs_main) [
[x] : float
]
]

View File

@@ -0,0 +1,4 @@
test/for_index_outside.ink:6,0: error: Use of undeclared symbol 'i'
 i += 1;
^


View File

@@ -0,0 +1,8 @@
scope (global) [
[vertex__vs_main] : ()
scope (vertex__vs_main) [
[b] : float2
[x] : float
[a] : float2
]
]

View File

@@ -0,0 +1,6 @@
test/temp_access.ink:5,10: error: Cannot assign to an lvalue.
 (a + b).x = 2.0;
^^^^^^^^^^^


View File

@@ -1,8 +1,11 @@
test/assign_arithmetic_expression.ink check test/assign_arithmetic_expression.ink check
test/arithmetic_parens.ink check
test/basic_property_and_return_value.ink check test/basic_property_and_return_value.ink check
test/builtin_types.ink check test/builtin_types.ink check
test/complicated_computation.ink check test/complicated_computation.ink check
test/constant_buffer.ink check test/constant_buffer.ink check
test/bad_double_access.ink check
test/double_access.ink check
test/empty_struct.ink check test/empty_struct.ink check
test/empty_vertex_main.ink check test/empty_vertex_main.ink check
test/empty_vertex_main_with_position_parameter.ink check test/empty_vertex_main_with_position_parameter.ink check
@@ -25,12 +28,14 @@ test/non_bool_cond.ink check
test/pass_and_access_struct_fields_in_functions.ink check test/pass_and_access_struct_fields_in_functions.ink check
test/passthrough.ink check test/passthrough.ink check
test/redeclared_variable.ink check test/redeclared_variable.ink check
test/rvalue_binary.ink check
test/simple_else_if.ink check test/simple_else_if.ink check
test/simple_if_else.ink check test/simple_if_else.ink check
test/simple_if.ink check test/simple_if.ink check
test/simple_struct_access.ink check test/simple_struct_access.ink check
test/struct_access_primitive_type.ink check test/struct_access_primitive_type.ink check
test/struct_within_struct.ink check test/struct_within_struct.ink check
test/temp_access.ink check
test/type_as_variable_name.ink check test/type_as_variable_name.ink check
test/unary.ink check test/unary.ink check
test/undeclared_function.ink check test/undeclared_function.ink check

View File

@@ -0,0 +1,6 @@
void vs_main()
{
float2 v;
v.x = (2.0f + ((4.0f - 2.0f) * 1.5f)) * 3.0f;
}

View File

@@ -1,5 +1,5 @@
void vs_main() void vs_main()
{ {
float x = (2.0f + 5.0f); float x = 2.0f + 5.0f;
} }

View File

@@ -21,8 +21,8 @@ void vs_main()
v4 = float4(2.0f, 2.0f, 2.0f, 2.0f); v4 = float4(2.0f, 2.0f, 2.0f, 2.0f);
v2.x = 2.0f; v2.x = 2.0f;
v2.y = 2.0f; v2.y = 2.0f;
float p = (v2.x + v3.z); float p = v2.x + v3.z;
float q = (v4.w + v2.x); float q = v4.w + v2.x;
float4x4 m; float4x4 m;
} }

View File

@@ -2,6 +2,6 @@ void vs_main()
{ {
float x = 5.0f; float x = 5.0f;
float y = 3000.0f; float y = 3000.0f;
float z = ((y * y) + x); float z = (y * y) + x;
} }

View File

@@ -8,7 +8,7 @@ int foo()
float bar() float bar()
{ {
return (1235.0f * 500); return 1235.0f * 500;
} }
void vs_main() void vs_main()

View File

@@ -7,7 +7,7 @@ struct Foo
float foo(Foo f) float foo(Foo f)
{ {
return (f.some_data * 2.0f); return f.some_data * 2.0f;
} }
void vs_main() void vs_main()

View File

@@ -0,0 +1,7 @@
void vs_main()
{
float2 a;
float2 b;
float x = (a + b).x;
}

View File

@@ -1,4 +1,5 @@
test/assign_arithmetic_expression.ink codegen test/assign_arithmetic_expression.ink codegen
test/arithmetic_parens.ink codegen
test/basic_property_and_return_value.ink codegen test/basic_property_and_return_value.ink codegen
test/builtin_types.ink codegen test/builtin_types.ink codegen
test/complicated_computation.ink codegen test/complicated_computation.ink codegen
@@ -19,6 +20,7 @@ test/multiple_semicolons_everywhere.ink codegen
test/nested_if.ink codegen test/nested_if.ink codegen
test/pass_and_access_struct_fields_in_functions.ink codegen test/pass_and_access_struct_fields_in_functions.ink codegen
test/passthrough.ink codegen test/passthrough.ink codegen
test/rvalue_binary.ink codegen
test/simple_else_if.ink codegen test/simple_else_if.ink codegen
test/simple_if_else.ink codegen test/simple_if_else.ink codegen
test/simple_if.ink codegen test/simple_if.ink codegen

View File

@@ -1,4 +1,5 @@
test/assign_arithmetic_expression.ink compile test/assign_arithmetic_expression.ink compile
test/arithmetic_parens.ink compile
test/basic_property_and_return_value.ink compile test/basic_property_and_return_value.ink compile
test/builtin_types.ink compile test/builtin_types.ink compile
test/complicated_computation.ink compile test/complicated_computation.ink compile
@@ -19,6 +20,7 @@ test/multiple_functions.ink compile
test/multiple_semicolons_everywhere.ink compile test/multiple_semicolons_everywhere.ink compile
test/pass_and_access_struct_fields_in_functions.ink compile test/pass_and_access_struct_fields_in_functions.ink compile
test/passthrough.ink compile test/passthrough.ink compile
test/rvalue_binary.ink compile
test/simple_else_if.ink compile test/simple_else_if.ink compile
test/simple_if_else.ink compile test/simple_if_else.ink compile
test/simple_if.ink compile test/simple_if.ink compile

View File

@@ -1,4 +1,4 @@
camera :: constant_buffer { camera :: Constant_Buffer {
projection : float4x4; projection : float4x4;
view : float4x4; view : float4x4;
} }

View File

@@ -1,4 +1,4 @@
p :: properties { p :: Constant_Buffer {
v : float2; v : float2;
} }

View File

@@ -0,0 +1,7 @@
vertex main :: () {
for i : 0..10 {
x : float;
}
i += 1;
}

View File

@@ -1,4 +1,4 @@
p :: constant_buffer @properties { p :: Constant_Buffer @properties {
color : float4; color : float4;
rect_position : float2; rect_position : float2;
rect_scale : float2; rect_scale : float2;

View File

@@ -0,0 +1,32 @@
{kind = TOKEN_VERTEX; ; index = 0 ; length = 6 line = 1 ; column = 0 ; value ='vertex'; }
{kind = TOKEN_IDENTIFIER; ; index = 7 ; length = 4 line = 1 ; column = 7 ; value ='main'; }
{kind = TOKEN_DOUBLECOLON; ; index = 12 ; length = 2 line = 1 ; column = 12 ; value ='::'; }
{kind = TOKEN_LEFTPAREN; ; index = 15 ; length = 1 line = 1 ; column = 15 ; value ='('; }
{kind = TOKEN_RIGHTPAREN; ; index = 16 ; length = 1 line = 1 ; column = 16 ; value =')'; }
{kind = TOKEN_LEFTBRACE; ; index = 18 ; length = 1 line = 1 ; column = 18 ; value ='{'; }
{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 1 line = 2 ; column = 0 ; value ='v'; }
{kind = TOKEN_COLON; ; index = 24 ; length = 1 line = 2 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 26 ; length = 6 line = 2 ; column = 4 ; value ='float2'; }
{kind = TOKEN_SEMICOLON; ; index = 32 ; length = 1 line = 2 ; column = 10 ; value =';'; }
{kind = TOKEN_IDENTIFIER; ; index = 36 ; length = 1 line = 3 ; column = 0 ; value ='v'; }
{kind = TOKEN_DOT; ; index = 37 ; length = 1 line = 3 ; column = 1 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 38 ; length = 1 line = 3 ; column = 2 ; value ='x'; }
{kind = TOKEN_ASSIGN; ; index = 40 ; length = 1 line = 3 ; column = 4 ; value ='='; }
{kind = TOKEN_LEFTPAREN; ; index = 42 ; length = 1 line = 3 ; column = 6 ; value ='('; }
{kind = TOKEN_FLOATLITERAL; ; index = 43 ; length = 3 line = 3 ; column = 7 ; value ='2'; }
{kind = TOKEN_PLUS; ; index = 47 ; length = 1 line = 3 ; column = 11 ; value ='+'; }
{kind = TOKEN_LEFTPAREN; ; index = 49 ; length = 1 line = 3 ; column = 13 ; value ='('; }
{kind = TOKEN_LEFTPAREN; ; index = 50 ; length = 1 line = 3 ; column = 14 ; value ='('; }
{kind = TOKEN_FLOATLITERAL; ; index = 51 ; length = 3 line = 3 ; column = 15 ; value ='4'; }
{kind = TOKEN_MINUS; ; index = 55 ; length = 1 line = 3 ; column = 19 ; value ='-'; }
{kind = TOKEN_FLOATLITERAL; ; index = 57 ; length = 3 line = 3 ; column = 21 ; value ='2'; }
{kind = TOKEN_RIGHTPAREN; ; index = 60 ; length = 1 line = 3 ; column = 24 ; value =')'; }
{kind = TOKEN_STAR; ; index = 62 ; length = 1 line = 3 ; column = 26 ; value ='*'; }
{kind = TOKEN_FLOATLITERAL; ; index = 64 ; length = 3 line = 3 ; column = 28 ; value ='1.5'; }
{kind = TOKEN_RIGHTPAREN; ; index = 67 ; length = 1 line = 3 ; column = 31 ; value =')'; }
{kind = TOKEN_RIGHTPAREN; ; index = 68 ; length = 1 line = 3 ; column = 32 ; value =')'; }
{kind = TOKEN_STAR; ; index = 70 ; length = 1 line = 3 ; column = 34 ; value ='*'; }
{kind = TOKEN_FLOATLITERAL; ; index = 72 ; length = 3 line = 3 ; column = 36 ; value ='3'; }
{kind = TOKEN_SEMICOLON; ; index = 75 ; length = 1 line = 3 ; column = 39 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 78 ; length = 1 line = 4 ; column = 0 ; value ='}'; }
{kind = TOKEN_EOF; ; index = 81 ; length = 0 line = 5 ; column = 0 ; value =''; }

View File

@@ -0,0 +1,31 @@
{kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 1 line = 1 ; column = 0 ; value ='P'; }
{kind = TOKEN_DOUBLECOLON; ; index = 2 ; length = 2 line = 1 ; column = 2 ; value ='::'; }
{kind = TOKEN_STRUCT; ; index = 5 ; length = 6 line = 1 ; column = 5 ; value ='struct'; }
{kind = TOKEN_LEFTBRACE; ; index = 12 ; length = 1 line = 1 ; column = 12 ; value ='{'; }
{kind = TOKEN_IDENTIFIER; ; index = 16 ; length = 1 line = 2 ; column = 0 ; value ='v'; }
{kind = TOKEN_COLON; ; index = 18 ; length = 1 line = 2 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 20 ; length = 6 line = 2 ; column = 4 ; value ='float2'; }
{kind = TOKEN_SEMICOLON; ; index = 26 ; length = 1 line = 2 ; column = 10 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 29 ; length = 1 line = 3 ; column = 0 ; value ='}'; }
{kind = TOKEN_VERTEX; ; index = 34 ; length = 6 line = 5 ; column = 0 ; value ='vertex'; }
{kind = TOKEN_IDENTIFIER; ; index = 41 ; length = 4 line = 5 ; column = 7 ; value ='main'; }
{kind = TOKEN_DOUBLECOLON; ; index = 46 ; length = 2 line = 5 ; column = 12 ; value ='::'; }
{kind = TOKEN_LEFTPAREN; ; index = 49 ; length = 1 line = 5 ; column = 15 ; value ='('; }
{kind = TOKEN_RIGHTPAREN; ; index = 50 ; length = 1 line = 5 ; column = 16 ; value =')'; }
{kind = TOKEN_LEFTBRACE; ; index = 52 ; length = 1 line = 5 ; column = 18 ; value ='{'; }
{kind = TOKEN_IDENTIFIER; ; index = 56 ; length = 1 line = 6 ; column = 0 ; value ='p'; }
{kind = TOKEN_COLON; ; index = 58 ; length = 1 line = 6 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 60 ; length = 1 line = 6 ; column = 4 ; value ='P'; }
{kind = TOKEN_SEMICOLON; ; index = 61 ; length = 1 line = 6 ; column = 5 ; value =';'; }
{kind = TOKEN_IDENTIFIER; ; index = 65 ; length = 1 line = 7 ; column = 0 ; value ='p'; }
{kind = TOKEN_DOT; ; index = 66 ; length = 1 line = 7 ; column = 1 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 67 ; length = 1 line = 7 ; column = 2 ; value ='v'; }
{kind = TOKEN_DOT; ; index = 68 ; length = 1 line = 7 ; column = 3 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 69 ; length = 1 line = 7 ; column = 4 ; value ='x'; }
{kind = TOKEN_DOT; ; index = 70 ; length = 1 line = 7 ; column = 5 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 71 ; length = 1 line = 7 ; column = 6 ; value ='y'; }
{kind = TOKEN_ASSIGN; ; index = 73 ; length = 1 line = 7 ; column = 8 ; value ='='; }
{kind = TOKEN_FLOATLITERAL; ; index = 75 ; length = 3 line = 7 ; column = 10 ; value ='2'; }
{kind = TOKEN_SEMICOLON; ; index = 78 ; length = 1 line = 7 ; column = 13 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 118 ; length = 1 line = 10 ; column = 0 ; value ='}'; }
{kind = TOKEN_EOF; ; index = 121 ; length = 0 line = 11 ; column = 0 ; value =''; }

View File

@@ -1,6 +1,6 @@
{kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 10 line = 1 ; column = 0 ; value ='properties'; } {kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 10 line = 1 ; column = 0 ; value ='properties'; }
{kind = TOKEN_DOUBLECOLON; ; index = 11 ; length = 2 line = 1 ; column = 11 ; value ='::'; } {kind = TOKEN_DOUBLECOLON; ; index = 11 ; length = 2 line = 1 ; column = 11 ; value ='::'; }
{kind = TOKEN_CONSTANT_BUFFER; ; index = 14 ; length = 15 line = 1 ; column = 14 ; value ='constant_buffer'; } {kind = TOKEN_CONSTANT_BUFFER; ; index = 14 ; length = 15 line = 1 ; column = 14 ; value ='Constant_Buffer'; }
{kind = TOKEN_AT; ; index = 30 ; length = 1 line = 1 ; column = 30 ; value ='@'; } {kind = TOKEN_AT; ; index = 30 ; length = 1 line = 1 ; column = 30 ; value ='@'; }
{kind = TOKEN_IDENTIFIER; ; index = 31 ; length = 10 line = 1 ; column = 31 ; value ='properties'; } {kind = TOKEN_IDENTIFIER; ; index = 31 ; length = 10 line = 1 ; column = 31 ; value ='properties'; }
{kind = TOKEN_LEFTBRACE; ; index = 42 ; length = 1 line = 1 ; column = 42 ; value ='{'; } {kind = TOKEN_LEFTBRACE; ; index = 42 ; length = 1 line = 1 ; column = 42 ; value ='{'; }

View File

@@ -1,6 +1,6 @@
{kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 6 line = 1 ; column = 0 ; value ='camera'; } {kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 6 line = 1 ; column = 0 ; value ='camera'; }
{kind = TOKEN_DOUBLECOLON; ; index = 7 ; length = 2 line = 1 ; column = 7 ; value ='::'; } {kind = TOKEN_DOUBLECOLON; ; index = 7 ; length = 2 line = 1 ; column = 7 ; value ='::'; }
{kind = TOKEN_CONSTANT_BUFFER; ; index = 10 ; length = 15 line = 1 ; column = 10 ; value ='constant_buffer'; } {kind = TOKEN_CONSTANT_BUFFER; ; index = 10 ; length = 15 line = 1 ; column = 10 ; value ='Constant_Buffer'; }
{kind = TOKEN_LEFTBRACE; ; index = 26 ; length = 1 line = 1 ; column = 26 ; value ='{'; } {kind = TOKEN_LEFTBRACE; ; index = 26 ; length = 1 line = 1 ; column = 26 ; value ='{'; }
{kind = TOKEN_IDENTIFIER; ; index = 30 ; length = 10 line = 2 ; column = 0 ; value ='projection'; } {kind = TOKEN_IDENTIFIER; ; index = 30 ; length = 10 line = 2 ; column = 0 ; value ='projection'; }
{kind = TOKEN_COLON; ; index = 41 ; length = 1 line = 2 ; column = 11 ; value =':'; } {kind = TOKEN_COLON; ; index = 41 ; length = 1 line = 2 ; column = 11 ; value =':'; }

View File

@@ -0,0 +1,33 @@
{kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 1 line = 1 ; column = 0 ; value ='p'; }
{kind = TOKEN_DOUBLECOLON; ; index = 2 ; length = 2 line = 1 ; column = 2 ; value ='::'; }
{kind = TOKEN_CONSTANT_BUFFER; ; index = 5 ; length = 15 line = 1 ; column = 5 ; value ='Constant_Buffer'; }
{kind = TOKEN_LEFTBRACE; ; index = 21 ; length = 1 line = 1 ; column = 21 ; value ='{'; }
{kind = TOKEN_IDENTIFIER; ; index = 25 ; length = 1 line = 2 ; column = 0 ; value ='v'; }
{kind = TOKEN_COLON; ; index = 27 ; length = 1 line = 2 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 29 ; length = 6 line = 2 ; column = 4 ; value ='float2'; }
{kind = TOKEN_SEMICOLON; ; index = 35 ; length = 1 line = 2 ; column = 10 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 38 ; length = 1 line = 3 ; column = 0 ; value ='}'; }
{kind = TOKEN_VERTEX; ; index = 43 ; length = 6 line = 5 ; column = 0 ; value ='vertex'; }
{kind = TOKEN_IDENTIFIER; ; index = 50 ; length = 4 line = 5 ; column = 7 ; value ='main'; }
{kind = TOKEN_DOUBLECOLON; ; index = 55 ; length = 2 line = 5 ; column = 12 ; value ='::'; }
{kind = TOKEN_LEFTPAREN; ; index = 57 ; length = 1 line = 5 ; column = 14 ; value ='('; }
{kind = TOKEN_RIGHTPAREN; ; index = 58 ; length = 1 line = 5 ; column = 15 ; value =')'; }
{kind = TOKEN_LEFTBRACE; ; index = 60 ; length = 1 line = 5 ; column = 17 ; value ='{'; }
{kind = TOKEN_IDENTIFIER; ; index = 64 ; length = 1 line = 6 ; column = 0 ; value ='x'; }
{kind = TOKEN_COLON; ; index = 66 ; length = 1 line = 6 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 68 ; length = 5 line = 6 ; column = 4 ; value ='float'; }
{kind = TOKEN_ASSIGN; ; index = 74 ; length = 1 line = 6 ; column = 10 ; value ='='; }
{kind = TOKEN_IDENTIFIER; ; index = 76 ; length = 1 line = 6 ; column = 12 ; value ='p'; }
{kind = TOKEN_DOT; ; index = 77 ; length = 1 line = 6 ; column = 13 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 78 ; length = 1 line = 6 ; column = 14 ; value ='v'; }
{kind = TOKEN_DOT; ; index = 79 ; length = 1 line = 6 ; column = 15 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 80 ; length = 1 line = 6 ; column = 16 ; value ='x'; }
{kind = TOKEN_SLASH; ; index = 82 ; length = 1 line = 6 ; column = 18 ; value ='/'; }
{kind = TOKEN_IDENTIFIER; ; index = 84 ; length = 1 line = 6 ; column = 20 ; value ='p'; }
{kind = TOKEN_DOT; ; index = 85 ; length = 1 line = 6 ; column = 21 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 86 ; length = 1 line = 6 ; column = 22 ; value ='v'; }
{kind = TOKEN_DOT; ; index = 87 ; length = 1 line = 6 ; column = 23 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 88 ; length = 1 line = 6 ; column = 24 ; value ='y'; }
{kind = TOKEN_SEMICOLON; ; index = 89 ; length = 1 line = 6 ; column = 25 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 92 ; length = 1 line = 7 ; column = 0 ; value ='}'; }
{kind = TOKEN_EOF; ; index = 95 ; length = 0 line = 8 ; column = 0 ; value =''; }

View File

@@ -1,6 +1,6 @@
{kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 1 line = 1 ; column = 0 ; value ='p'; } {kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 1 line = 1 ; column = 0 ; value ='p'; }
{kind = TOKEN_DOUBLECOLON; ; index = 2 ; length = 2 line = 1 ; column = 2 ; value ='::'; } {kind = TOKEN_DOUBLECOLON; ; index = 2 ; length = 2 line = 1 ; column = 2 ; value ='::'; }
{kind = TOKEN_CONSTANT_BUFFER; ; index = 5 ; length = 15 line = 1 ; column = 5 ; value ='constant_buffer'; } {kind = TOKEN_CONSTANT_BUFFER; ; index = 5 ; length = 15 line = 1 ; column = 5 ; value ='Constant_Buffer'; }
{kind = TOKEN_AT; ; index = 21 ; length = 1 line = 1 ; column = 21 ; value ='@'; } {kind = TOKEN_AT; ; index = 21 ; length = 1 line = 1 ; column = 21 ; value ='@'; }
{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 10 line = 1 ; column = 22 ; value ='properties'; } {kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 10 line = 1 ; column = 22 ; value ='properties'; }
{kind = TOKEN_LEFTBRACE; ; index = 33 ; length = 1 line = 1 ; column = 33 ; value ='{'; } {kind = TOKEN_LEFTBRACE; ; index = 33 ; length = 1 line = 1 ; column = 33 ; value ='{'; }

View File

@@ -0,0 +1,27 @@
{kind = TOKEN_VERTEX; ; index = 0 ; length = 6 line = 1 ; column = 0 ; value ='vertex'; }
{kind = TOKEN_IDENTIFIER; ; index = 7 ; length = 4 line = 1 ; column = 7 ; value ='main'; }
{kind = TOKEN_DOUBLECOLON; ; index = 12 ; length = 2 line = 1 ; column = 12 ; value ='::'; }
{kind = TOKEN_LEFTPAREN; ; index = 15 ; length = 1 line = 1 ; column = 15 ; value ='('; }
{kind = TOKEN_RIGHTPAREN; ; index = 16 ; length = 1 line = 1 ; column = 16 ; value =')'; }
{kind = TOKEN_LEFTBRACE; ; index = 18 ; length = 1 line = 1 ; column = 18 ; value ='{'; }
{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 1 line = 2 ; column = 0 ; value ='a'; }
{kind = TOKEN_COLON; ; index = 24 ; length = 1 line = 2 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 26 ; length = 6 line = 2 ; column = 4 ; value ='float2'; }
{kind = TOKEN_SEMICOLON; ; index = 32 ; length = 1 line = 2 ; column = 10 ; value =';'; }
{kind = TOKEN_IDENTIFIER; ; index = 36 ; length = 1 line = 3 ; column = 0 ; value ='b'; }
{kind = TOKEN_COLON; ; index = 38 ; length = 1 line = 3 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 40 ; length = 6 line = 3 ; column = 4 ; value ='float2'; }
{kind = TOKEN_SEMICOLON; ; index = 46 ; length = 1 line = 3 ; column = 10 ; value =';'; }
{kind = TOKEN_IDENTIFIER; ; index = 52 ; length = 1 line = 5 ; column = 0 ; value ='x'; }
{kind = TOKEN_COLON; ; index = 54 ; length = 1 line = 5 ; column = 2 ; value =':'; }
{kind = TOKEN_ASSIGN; ; index = 55 ; length = 1 line = 5 ; column = 3 ; value ='='; }
{kind = TOKEN_LEFTPAREN; ; index = 57 ; length = 1 line = 5 ; column = 5 ; value ='('; }
{kind = TOKEN_IDENTIFIER; ; index = 58 ; length = 1 line = 5 ; column = 6 ; value ='a'; }
{kind = TOKEN_PLUS; ; index = 60 ; length = 1 line = 5 ; column = 8 ; value ='+'; }
{kind = TOKEN_IDENTIFIER; ; index = 62 ; length = 1 line = 5 ; column = 10 ; value ='b'; }
{kind = TOKEN_RIGHTPAREN; ; index = 63 ; length = 1 line = 5 ; column = 11 ; value =')'; }
{kind = TOKEN_DOT; ; index = 64 ; length = 1 line = 5 ; column = 12 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 65 ; length = 1 line = 5 ; column = 13 ; value ='x'; }
{kind = TOKEN_SEMICOLON; ; index = 66 ; length = 1 line = 5 ; column = 14 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 69 ; length = 1 line = 6 ; column = 0 ; value ='}'; }
{kind = TOKEN_EOF; ; index = 72 ; length = 0 line = 7 ; column = 0 ; value =''; }

View File

@@ -0,0 +1,26 @@
{kind = TOKEN_VERTEX; ; index = 0 ; length = 6 line = 1 ; column = 0 ; value ='vertex'; }
{kind = TOKEN_IDENTIFIER; ; index = 7 ; length = 4 line = 1 ; column = 7 ; value ='main'; }
{kind = TOKEN_DOUBLECOLON; ; index = 12 ; length = 2 line = 1 ; column = 12 ; value ='::'; }
{kind = TOKEN_LEFTPAREN; ; index = 15 ; length = 1 line = 1 ; column = 15 ; value ='('; }
{kind = TOKEN_RIGHTPAREN; ; index = 16 ; length = 1 line = 1 ; column = 16 ; value =')'; }
{kind = TOKEN_LEFTBRACE; ; index = 18 ; length = 1 line = 1 ; column = 18 ; value ='{'; }
{kind = TOKEN_IDENTIFIER; ; index = 22 ; length = 1 line = 2 ; column = 0 ; value ='a'; }
{kind = TOKEN_COLON; ; index = 24 ; length = 1 line = 2 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 26 ; length = 6 line = 2 ; column = 4 ; value ='float2'; }
{kind = TOKEN_SEMICOLON; ; index = 32 ; length = 1 line = 2 ; column = 10 ; value =';'; }
{kind = TOKEN_IDENTIFIER; ; index = 36 ; length = 1 line = 3 ; column = 0 ; value ='b'; }
{kind = TOKEN_COLON; ; index = 38 ; length = 1 line = 3 ; column = 2 ; value =':'; }
{kind = TOKEN_IDENTIFIER; ; index = 40 ; length = 6 line = 3 ; column = 4 ; value ='float2'; }
{kind = TOKEN_SEMICOLON; ; index = 46 ; length = 1 line = 3 ; column = 10 ; value =';'; }
{kind = TOKEN_LEFTPAREN; ; index = 52 ; length = 1 line = 5 ; column = 0 ; value ='('; }
{kind = TOKEN_IDENTIFIER; ; index = 53 ; length = 1 line = 5 ; column = 1 ; value ='a'; }
{kind = TOKEN_PLUS; ; index = 55 ; length = 1 line = 5 ; column = 3 ; value ='+'; }
{kind = TOKEN_IDENTIFIER; ; index = 57 ; length = 1 line = 5 ; column = 5 ; value ='b'; }
{kind = TOKEN_RIGHTPAREN; ; index = 58 ; length = 1 line = 5 ; column = 6 ; value =')'; }
{kind = TOKEN_DOT; ; index = 59 ; length = 1 line = 5 ; column = 7 ; value ='.'; }
{kind = TOKEN_IDENTIFIER; ; index = 60 ; length = 1 line = 5 ; column = 8 ; value ='x'; }
{kind = TOKEN_ASSIGN; ; index = 62 ; length = 1 line = 5 ; column = 10 ; value ='='; }
{kind = TOKEN_FLOATLITERAL; ; index = 64 ; length = 3 line = 5 ; column = 12 ; value ='2'; }
{kind = TOKEN_SEMICOLON; ; index = 67 ; length = 1 line = 5 ; column = 15 ; value =';'; }
{kind = TOKEN_RIGHTBRACE; ; index = 70 ; length = 1 line = 6 ; column = 0 ; value ='}'; }
{kind = TOKEN_EOF; ; index = 73 ; length = 0 line = 7 ; column = 0 ; value =''; }

View File

@@ -1,8 +1,11 @@
test/assign_arithmetic_expression.ink lex test/assign_arithmetic_expression.ink lex
test/arithmetic_parens.ink lex
test/bad_double_access.ink lex
test/basic_property_and_return_value.ink lex test/basic_property_and_return_value.ink lex
test/builtin_types.ink lex test/builtin_types.ink lex
test/complicated_computation.ink lex test/complicated_computation.ink lex
test/constant_buffer.ink lex test/constant_buffer.ink lex
test/double_access.ink lex
test/else_if_after_else.ink lex test/else_if_after_else.ink lex
test/empty_struct.ink lex test/empty_struct.ink lex
test/empty_vertex_main.ink lex test/empty_vertex_main.ink lex
@@ -33,12 +36,14 @@ test/non_bool_cond.ink lex
test/pass_and_access_struct_fields_in_functions.ink lex test/pass_and_access_struct_fields_in_functions.ink lex
test/passthrough.ink lex test/passthrough.ink lex
test/redeclared_variable.ink lex test/redeclared_variable.ink lex
test/rvalue_binary.ink lex
test/simple_else_if.ink lex test/simple_else_if.ink lex
test/simple_if_else.ink lex test/simple_if_else.ink lex
test/simple_if.ink lex test/simple_if.ink lex
test/simple_struct_access.ink lex test/simple_struct_access.ink lex
test/struct_access_primitive_type.ink lex test/struct_access_primitive_type.ink lex
test/struct_within_struct.ink lex test/struct_within_struct.ink lex
test/temp_access.ink lex
test/type_as_variable_name.ink lex test/type_as_variable_name.ink lex
test/unary.ink lex test/unary.ink lex
test/undeclared_function.ink lex test/undeclared_function.ink lex

View File

@@ -0,0 +1,5 @@
(program
(fun vertex vs_main
[]
(:= v float2)
(= v.x (* (+ 2 (* (- 4 2) 1.5)) 3))))

View File

@@ -0,0 +1,8 @@
(program
(struct P
[(:= v float2)])
(fun vertex vs_main
[]
(:= p P)
(= p.v.x.y 2)))

10
test/parse/buffers.golden Normal file
View File

@@ -0,0 +1,10 @@
(program
(buffer property_buffer
[(:= color float4)])
(constant_buffer cbuffer
[(:= color float4)])
(fun pixel ps_main
[(:= index int)]
(return property_buffer[index].color)))

View File

@@ -0,0 +1,7 @@
(program
(constant_buffer p
[(:= v float2)])
(fun vertex vs_main
[]
(:= x float (/ p.v.x p.v.y))))

View File

@@ -0,0 +1,6 @@
(program
(fun vertex vs_main
[]
(:= a float2)
(:= b float2)
(:= x (+ a b).x)))

View File

@@ -0,0 +1,6 @@
(program
(fun vertex vs_main
[]
(:= a float2)
(:= b float2)
(= (+ a b).x 2)))

View File

@@ -1,8 +1,11 @@
test/assign_arithmetic_expression.ink parse test/assign_arithmetic_expression.ink parse
test/arithmetic_parens.ink parse
test/bad_double_access.ink parse
test/basic_property_and_return_value.ink parse test/basic_property_and_return_value.ink parse
test/builtin_types.ink parse test/builtin_types.ink parse
test/complicated_computation.ink parse test/complicated_computation.ink parse
test/constant_buffer.ink parse test/constant_buffer.ink parse
test/double_access.ink parse
test/else_if_after_else.ink parse test/else_if_after_else.ink parse
test/empty_struct.ink parse test/empty_struct.ink parse
test/empty_vertex_main.ink parse test/empty_vertex_main.ink parse
@@ -33,12 +36,14 @@ test/non_bool_cond.ink parse
test/pass_and_access_struct_fields_in_functions.ink parse test/pass_and_access_struct_fields_in_functions.ink parse
test/passthrough.ink parse test/passthrough.ink parse
test/redeclared_variable.ink parse test/redeclared_variable.ink parse
test/rvalue_binary.ink parse
test/simple_else_if.ink parse test/simple_else_if.ink parse
test/simple_if_else.ink parse test/simple_if_else.ink parse
test/simple_if.ink parse test/simple_if.ink parse
test/simple_struct_access.ink parse test/simple_struct_access.ink parse
test/struct_access_primitive_type.ink parse test/struct_access_primitive_type.ink parse
test/struct_within_struct.ink parse test/struct_within_struct.ink parse
test/temp_access.ink parse
test/type_as_variable_name.ink parse test/type_as_variable_name.ink parse
test/unary.ink parse test/unary.ink parse
test/undeclared_function.ink parse test/undeclared_function.ink parse

6
test/rvalue_binary.ink Normal file
View File

@@ -0,0 +1,6 @@
vertex main :: () {
a : float2;
b : float2;
x := (a + b).x;
}

6
test/temp_access.ink Normal file
View File

@@ -0,0 +1,6 @@
vertex main :: () {
a : float2;
b : float2;
(a + b).x = 2.0;
}