Add lexing, parsing and some semantic checking for constant buffers.
This commit is contained in:
8
AST.jai
8
AST.jai
@@ -20,6 +20,7 @@ AST_Kind :: enum {
|
|||||||
// Operator;
|
// Operator;
|
||||||
Call;
|
Call;
|
||||||
Struct;
|
Struct;
|
||||||
|
CBuffer;
|
||||||
FieldList;
|
FieldList;
|
||||||
ArgList;
|
ArgList;
|
||||||
Variable;
|
Variable;
|
||||||
@@ -39,7 +40,8 @@ AST_Node :: struct {
|
|||||||
|
|
||||||
// @Note(niels): Children nodes can be interpreted as anything useful.
|
// @Note(niels): Children nodes can be interpreted as anything useful.
|
||||||
// for an if-statement we would have at most 2 children
|
// for an if-statement we would have at most 2 children
|
||||||
// a property block has a child node for each field declaration etc.
|
// a property block has a field list child node which has
|
||||||
|
// a child node for each field declaration etc.
|
||||||
children : [..]*AST_Node;
|
children : [..]*AST_Node;
|
||||||
parent : *AST_Node;
|
parent : *AST_Node;
|
||||||
|
|
||||||
@@ -52,8 +54,6 @@ AST_Node :: struct {
|
|||||||
|
|
||||||
token : Token;
|
token : Token;
|
||||||
|
|
||||||
assignment : bool;
|
|
||||||
|
|
||||||
source_location : Source_Range;
|
source_location : Source_Range;
|
||||||
|
|
||||||
type_variable : Type_Variable_Handle;
|
type_variable : Type_Variable_Handle;
|
||||||
@@ -312,6 +312,8 @@ pretty_print_declaration :: (declaration : *AST_Node, indentation : int, builder
|
|||||||
else {
|
else {
|
||||||
if declaration.kind == .Struct {
|
if declaration.kind == .Struct {
|
||||||
append(builder, "struct ");
|
append(builder, "struct ");
|
||||||
|
} else if declaration.kind == .CBuffer {
|
||||||
|
append(builder, "constant_buffer ");
|
||||||
}
|
}
|
||||||
print_to_builder(builder, "%", declaration.name);
|
print_to_builder(builder, "%", declaration.name);
|
||||||
}
|
}
|
||||||
|
|||||||
117
Lexing.jai
117
Lexing.jai
@@ -64,6 +64,7 @@ Token_Kind :: enum {
|
|||||||
TOKEN_CBUFFER;
|
TOKEN_CBUFFER;
|
||||||
TOKEN_COLUMNMAJOR;
|
TOKEN_COLUMNMAJOR;
|
||||||
TOKEN_CONST;
|
TOKEN_CONST;
|
||||||
|
TOKEN_CONSTANT_BUFFER;
|
||||||
TOKEN_CONTINUE;
|
TOKEN_CONTINUE;
|
||||||
|
|
||||||
TOKEN_DEFAULT;
|
TOKEN_DEFAULT;
|
||||||
@@ -129,6 +130,7 @@ Token :: struct {
|
|||||||
|
|
||||||
source : *u8;
|
source : *u8;
|
||||||
|
|
||||||
|
// This could all be derived on demand
|
||||||
line : int;
|
line : int;
|
||||||
length : int;
|
length : int;
|
||||||
column : int;
|
column : int;
|
||||||
@@ -218,6 +220,7 @@ identifier_kind :: (using lexer : *Lexer) -> Token_Kind {
|
|||||||
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 == "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;
|
||||||
@@ -496,8 +499,66 @@ scan_next_token :: (lexer : *Lexer) -> *Token {
|
|||||||
// return error_token(lexer, tprint("Invalid token: %", s));
|
// return error_token(lexer, tprint("Invalid token: %", s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lex :: (lexer : *Lexer, allocator : Allocator = context.allocator) -> Lexing_Result {
|
||||||
|
lexer.result.tokens.allocator = allocator;
|
||||||
|
token : *Token = scan_next_token(lexer);
|
||||||
|
while token && token.kind != .TOKEN_EOF {
|
||||||
|
token = scan_next_token(lexer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lexer.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_lexer_from_string :: (lexer : *Lexer, input : string) {
|
||||||
|
ok := read_input_from_string(lexer, input);
|
||||||
|
if !ok {
|
||||||
|
record_error(lexer, "Unable to initialize from string\n");
|
||||||
|
lexer.result.had_error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_lexer_from_file :: (lexer : *Lexer, file_path : string) {
|
||||||
|
ok := read_input_from_file(lexer, file_path);
|
||||||
|
if !ok {
|
||||||
|
record_error(lexer, tprint("Unable to read file: %\n", file_path));
|
||||||
|
lexer.result.had_error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read_input_from_string :: (lexer : *Lexer, input : string) -> bool {
|
||||||
|
lexer.input = input;
|
||||||
|
lexer.cursor = 0;
|
||||||
|
lexer.start = 0;
|
||||||
|
lexer.current_line = 1;
|
||||||
|
lexer.current_column = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_input_from_file :: (lexer : *Lexer, file_path : string) -> bool {
|
||||||
|
assert(file_path != "");
|
||||||
|
|
||||||
|
value, success := read_entire_file(file_path, true, true);
|
||||||
|
if !success {
|
||||||
|
free(value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer.path = copy_string(file_path);
|
||||||
|
lexer.input = value;
|
||||||
|
lexer.cursor = 0;
|
||||||
|
lexer.start = 0;
|
||||||
|
lexer.current_line = 1;
|
||||||
|
lexer.current_column = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Pretty printing
|
||||||
pretty_print_token :: (token : *Token, builder : *String_Builder) {
|
pretty_print_token :: (token : *Token, builder : *String_Builder) {
|
||||||
MAX :: 18;
|
MAX :: 21;
|
||||||
kind_name := enum_names(Token_Kind)[cast(int)token.kind];
|
kind_name := enum_names(Token_Kind)[cast(int)token.kind];
|
||||||
diff := MAX - kind_name.count;
|
diff := MAX - kind_name.count;
|
||||||
|
|
||||||
@@ -637,59 +698,5 @@ print_from_source_location :: (source_location : Source_Range, allocator := cont
|
|||||||
return builder_to_string(*builder,, allocator);
|
return builder_to_string(*builder,, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
lex :: (lexer : *Lexer, allocator : Allocator = context.allocator) -> Lexing_Result {
|
|
||||||
lexer.result.tokens.allocator = allocator;
|
|
||||||
token : *Token = scan_next_token(lexer);
|
|
||||||
while token && token.kind != .TOKEN_EOF {
|
|
||||||
token = scan_next_token(lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return lexer.result;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_lexer_from_string :: (lexer : *Lexer, input : string) {
|
|
||||||
ok := read_input_from_string(lexer, input);
|
|
||||||
if !ok {
|
|
||||||
record_error(lexer, "Unable to initialize from string\n");
|
|
||||||
lexer.result.had_error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init_lexer_from_file :: (lexer : *Lexer, file_path : string) {
|
|
||||||
ok := read_input_from_file(lexer, file_path);
|
|
||||||
if !ok {
|
|
||||||
record_error(lexer, tprint("Unable to read file: %\n", file_path));
|
|
||||||
lexer.result.had_error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
read_input_from_string :: (lexer : *Lexer, input : string) -> bool {
|
|
||||||
lexer.input = input;
|
|
||||||
lexer.cursor = 0;
|
|
||||||
lexer.start = 0;
|
|
||||||
lexer.current_line = 1;
|
|
||||||
lexer.current_column = 0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
read_input_from_file :: (lexer : *Lexer, file_path : string) -> bool {
|
|
||||||
assert(file_path != "");
|
|
||||||
|
|
||||||
value, success := read_entire_file(file_path, true, true);
|
|
||||||
if !success {
|
|
||||||
free(value);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lexer.path = copy_string(file_path);
|
|
||||||
lexer.input = value;
|
|
||||||
lexer.cursor = 0;
|
|
||||||
lexer.start = 0;
|
|
||||||
lexer.current_line = 1;
|
|
||||||
lexer.current_column = 0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#import "Basic";
|
#import "Basic";
|
||||||
|
|||||||
22
Parsing.jai
22
Parsing.jai
@@ -883,6 +883,26 @@ property_block :: (parse_state : *Parse_State, identifier_token : *Token = null)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constant_buffer :: (parse_state : *Parse_State, identifier_token : *Token = null) -> *AST_Node {
|
||||||
|
node : *AST_Node;
|
||||||
|
source_location : Source_Range;
|
||||||
|
source_location.begin = parse_state.current;
|
||||||
|
consume(parse_state, .TOKEN_LEFTBRACE, "Expect '{' after 'constant_buffer' keyword");
|
||||||
|
buffer := field_list(parse_state, .Semicolon);
|
||||||
|
|
||||||
|
node = make_node(parse_state, .CBuffer);
|
||||||
|
if identifier_token {
|
||||||
|
node.name = identifier_token.ident_value;
|
||||||
|
}
|
||||||
|
add_child(node, buffer);
|
||||||
|
|
||||||
|
consume(parse_state, .TOKEN_RIGHTBRACE, "Expect '}' after 'constant_buffer' block");
|
||||||
|
source_location.end = parse_state.previous;
|
||||||
|
node.source_location = source_location;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
struct_declaration :: (parse_state : *Parse_State, identifier_token : *Token) -> *AST_Node {
|
struct_declaration :: (parse_state : *Parse_State, identifier_token : *Token) -> *AST_Node {
|
||||||
source_location := generate_source_location_from_token(parse_state, identifier_token);
|
source_location := generate_source_location_from_token(parse_state, identifier_token);
|
||||||
|
|
||||||
@@ -914,6 +934,8 @@ const_declaration :: (parse_state : *Parse_State, identifier_token : *Token) ->
|
|||||||
return function_declaration(parse_state, identifier_token, .None);
|
return function_declaration(parse_state, identifier_token, .None);
|
||||||
} else if match(parse_state, .TOKEN_PROPERTIES) {
|
} else if match(parse_state, .TOKEN_PROPERTIES) {
|
||||||
return property_block(parse_state, identifier_token);
|
return property_block(parse_state, identifier_token);
|
||||||
|
} else if match(parse_state, .TOKEN_CONSTANT_BUFFER) {
|
||||||
|
return constant_buffer(parse_state, identifier_token);
|
||||||
}
|
}
|
||||||
return error_node(parse_state, tprint("Couldn't parse constant declaration at token %\n", parse_state.current.*));
|
return error_node(parse_state, tprint("Couldn't parse constant declaration at token %\n", parse_state.current.*));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -829,6 +829,9 @@ proper_type_to_string :: (checker : *Semantic_Checker, var : Type_Variable, allo
|
|||||||
proper_type_to_string(*builder, checker, var);
|
proper_type_to_string(*builder, checker, var);
|
||||||
return builder_to_string(*builder,, allocator);
|
return builder_to_string(*builder,, allocator);
|
||||||
}
|
}
|
||||||
|
case .Struct; {
|
||||||
|
return var.typename;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "______not proper type______";
|
return "______not proper type______";
|
||||||
@@ -916,12 +919,25 @@ declare_struct :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variab
|
|||||||
return declare_struct(checker, node, node.name);
|
return declare_struct(checker, node, node.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROPERTIES_BUFFER_INDEX : u32 : 0;
|
||||||
|
META_BUFFER_INDEX : u32 : PROPERTIES_BUFFER_INDEX + 1;
|
||||||
|
current_custom_buffer_index : u32 = META_BUFFER_INDEX + 1;
|
||||||
|
|
||||||
declare_properties :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_Handle {
|
declare_properties :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||||
name := ifx node.name.count == 0 then "properties" else node.name;
|
name := ifx node.name.count == 0 then "properties" else node.name;
|
||||||
type_var := declare_struct(checker, node, name);
|
type_var := declare_struct(checker, node, name);
|
||||||
var := h2tv(checker, type_var);
|
var := h2tv(checker, type_var);
|
||||||
var.typename = "properties";
|
var.typename = "properties";
|
||||||
var.buffer_index = 0;
|
var.buffer_index = PROPERTIES_BUFFER_INDEX;
|
||||||
|
return type_var;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_cbuffer :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_Handle {
|
||||||
|
type_var := declare_struct(checker, node);
|
||||||
|
var := h2tv(checker, type_var);
|
||||||
|
var.typename = "constant_buffer";
|
||||||
|
current_custom_buffer_index += 1;
|
||||||
|
var.buffer_index = current_custom_buffer_index;
|
||||||
return type_var;
|
return type_var;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -930,7 +946,7 @@ declare_meta :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable
|
|||||||
type_var := declare_struct(checker, node, name);
|
type_var := declare_struct(checker, node, name);
|
||||||
var := h2tv(checker, type_var);
|
var := h2tv(checker, type_var);
|
||||||
var.typename = name;
|
var.typename = name;
|
||||||
var.buffer_index = 0;
|
var.buffer_index = META_BUFFER_INDEX;
|
||||||
return type_var;
|
return type_var;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1204,7 +1220,7 @@ create_variable :: (checker : *Semantic_Checker, node : *AST_Node, field_parent
|
|||||||
field_access_on_primitive_type(checker, node, find_result.type_variable);
|
field_access_on_primitive_type(checker, node, find_result.type_variable);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
lookup_name : string;
|
lookup_name : string = variable.typename;
|
||||||
if variable.typename == "properties" {
|
if variable.typename == "properties" {
|
||||||
lookup_name = variable.name;
|
lookup_name = variable.name;
|
||||||
}
|
}
|
||||||
@@ -1306,6 +1322,34 @@ create_call_constraint :: (checker : *Semantic_Checker, node : *AST_Node, type_v
|
|||||||
overload_found := false;
|
overload_found := false;
|
||||||
arg_node : *AST_Node = null;
|
arg_node : *AST_Node = null;
|
||||||
|
|
||||||
|
Result :: struct {
|
||||||
|
var : Type_Variable_Handle;
|
||||||
|
node : *AST_Node;
|
||||||
|
}
|
||||||
|
arg_vars : [..]Result;
|
||||||
|
|
||||||
|
// @incomplete(niels): Should be some kind of scratch allocator instead probably?
|
||||||
|
arg_vars.allocator = temp;
|
||||||
|
arg_count := 0;
|
||||||
|
|
||||||
|
for child : node.children {
|
||||||
|
if child.kind == {
|
||||||
|
case .ArgList; {
|
||||||
|
arg_count = child.children.count;
|
||||||
|
for arg_child : child.children {
|
||||||
|
arg_var := check_node(checker, arg_child);
|
||||||
|
if arg_var != 0 {
|
||||||
|
array_add(*arg_vars, .{ arg_var, arg_child });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if arg_vars.count != arg_count {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for *func : find_result.functions {
|
for *func : find_result.functions {
|
||||||
if overload_found {
|
if overload_found {
|
||||||
break;
|
break;
|
||||||
@@ -1313,6 +1357,10 @@ create_call_constraint :: (checker : *Semantic_Checker, node : *AST_Node, type_v
|
|||||||
|
|
||||||
function := h2tv(checker, func.type_variable);
|
function := h2tv(checker, func.type_variable);
|
||||||
|
|
||||||
|
if arg_count != function.child_count {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if function.return_var > 0 {
|
if function.return_var > 0 {
|
||||||
return_var := h2tv(checker, function.return_var);
|
return_var := h2tv(checker, function.return_var);
|
||||||
constrained_var := h2tv(checker, type_var);
|
constrained_var := h2tv(checker, type_var);
|
||||||
@@ -1327,16 +1375,7 @@ create_call_constraint :: (checker : *Semantic_Checker, node : *AST_Node, type_v
|
|||||||
|
|
||||||
all_args_match : bool = true;
|
all_args_match : bool = true;
|
||||||
|
|
||||||
for child : node.children {
|
for arg : arg_vars {
|
||||||
if child.kind == {
|
|
||||||
case .ArgList; {
|
|
||||||
if child.children.count != function.child_count {
|
|
||||||
// mismatched_arguments(checker, node, func, child.children.count, function.child_count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for arg_child : child.children {
|
|
||||||
arg_var := check_node(checker, arg_child);
|
|
||||||
function_param := function.children[it_index];
|
function_param := function.children[it_index];
|
||||||
|
|
||||||
// @Incomplete(nb): Improve the error handling of this constraint.
|
// @Incomplete(nb): Improve the error handling of this constraint.
|
||||||
@@ -1349,10 +1388,10 @@ create_call_constraint :: (checker : *Semantic_Checker, node : *AST_Node, type_v
|
|||||||
// @Update(nb): We actually do this now for a bunch of places, but not all.
|
// @Update(nb): We actually do this now for a bunch of places, but not all.
|
||||||
// Error reporting in this case is still not great, since it doesn't properly mark the
|
// Error reporting in this case is still not great, since it doesn't properly mark the
|
||||||
// faulty variable.
|
// faulty variable.
|
||||||
create_equivalence_constraint(checker, arg_var, function_param, arg_child);
|
create_equivalence_constraint(checker, arg.var, function_param, arg.node);
|
||||||
if !types_compatible(checker, arg_var, function_param) {
|
if !types_compatible(checker, arg.var, function_param) {
|
||||||
if all_args_match {
|
if all_args_match {
|
||||||
arg_node = arg_child;
|
arg_node = arg.node;
|
||||||
}
|
}
|
||||||
all_args_match = false;
|
all_args_match = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -1360,9 +1399,6 @@ create_call_constraint :: (checker : *Semantic_Checker, node : *AST_Node, type_v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !overload_found {
|
if !overload_found {
|
||||||
no_matching_overload_found(checker, node, find_result, arg_node);
|
no_matching_overload_found(checker, node, find_result, arg_node);
|
||||||
@@ -1478,6 +1514,8 @@ traverse :: (checker : *Semantic_Checker, root : *AST_Node) {
|
|||||||
declare_struct(checker, declaration);
|
declare_struct(checker, declaration);
|
||||||
} else if declaration.kind == .Meta {
|
} else if declaration.kind == .Meta {
|
||||||
declare_meta(checker, declaration);
|
declare_meta(checker, declaration);
|
||||||
|
} else if declaration.kind == .CBuffer {
|
||||||
|
declare_cbuffer(checker, declaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
test/assign_arithmetic_expression.shd codegen
|
test/assign_arithmetic_expression.shd codegen
|
||||||
test/basic_property_and_return_value.shd codegen
|
test/basic_property_and_return_value.shd codegen
|
||||||
test/complicated_computation.shd codegen
|
test/complicated_computation.shd codegen
|
||||||
|
test/constant_buffer.shd codegen
|
||||||
test/empty_struct.shd codegen
|
test/empty_struct.shd codegen
|
||||||
test/empty_vertex_main.shd codegen
|
test/empty_vertex_main.shd codegen
|
||||||
test/empty_vertex_main_with_position_parameter.shd codegen
|
test/empty_vertex_main_with_position_parameter.shd codegen
|
||||||
|
|||||||
12
test/constant_buffer.shd
Normal file
12
test/constant_buffer.shd
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Camera_Data :: constant_buffer {
|
||||||
|
projection : float4x4;
|
||||||
|
view : float4x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex main :: (pos : float4 @position) -> float4 @position {
|
||||||
|
return mul(projection, mul(view, pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel main :: () -> float4 @target {
|
||||||
|
return float(0.5, 0.5, 0.5, 1.0);
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
vertex main :: (pos : float3) -> int {
|
vertex main :: (pos : float3) -> int {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
66
test/lex/constant_buffer.golden
Normal file
66
test/lex/constant_buffer.golden
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 0 ; length = 11 line = 1 ; column = 0 ; value ='Camera_Data'; }
|
||||||
|
{kind = TOKEN_DOUBLECOLON; ; index = 12 ; length = 2 line = 1 ; column = 12 ; value ='::'; }
|
||||||
|
{kind = TOKEN_CONSTANT_BUFFER; ; index = 15 ; length = 15 line = 1 ; column = 15 ; value ='constant_buffer'; }
|
||||||
|
{kind = TOKEN_LEFTBRACE; ; index = 31 ; length = 1 line = 1 ; column = 31 ; value ='{'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 35 ; length = 10 line = 2 ; column = 0 ; value ='projection'; }
|
||||||
|
{kind = TOKEN_COLON; ; index = 46 ; length = 1 line = 2 ; column = 11 ; value =':'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 48 ; length = 8 line = 2 ; column = 13 ; value ='float4x4'; }
|
||||||
|
{kind = TOKEN_SEMICOLON; ; index = 56 ; length = 1 line = 2 ; column = 21 ; value =';'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 60 ; length = 4 line = 3 ; column = 0 ; value ='view'; }
|
||||||
|
{kind = TOKEN_COLON; ; index = 71 ; length = 1 line = 3 ; column = 11 ; value =':'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 73 ; length = 8 line = 3 ; column = 13 ; value ='float4x4'; }
|
||||||
|
{kind = TOKEN_SEMICOLON; ; index = 81 ; length = 1 line = 3 ; column = 21 ; value =';'; }
|
||||||
|
{kind = TOKEN_RIGHTBRACE; ; index = 84 ; length = 1 line = 4 ; column = 0 ; value ='}'; }
|
||||||
|
{kind = TOKEN_VERTEX; ; index = 89 ; length = 6 line = 6 ; column = 0 ; value ='vertex'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 96 ; length = 4 line = 6 ; column = 7 ; value ='main'; }
|
||||||
|
{kind = TOKEN_DOUBLECOLON; ; index = 101 ; length = 2 line = 6 ; column = 12 ; value ='::'; }
|
||||||
|
{kind = TOKEN_LEFTPAREN; ; index = 104 ; length = 1 line = 6 ; column = 15 ; value ='('; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 105 ; length = 3 line = 6 ; column = 16 ; value ='pos'; }
|
||||||
|
{kind = TOKEN_COLON; ; index = 109 ; length = 1 line = 6 ; column = 20 ; value =':'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 111 ; length = 6 line = 6 ; column = 22 ; value ='float4'; }
|
||||||
|
{kind = TOKEN_AT; ; index = 118 ; length = 1 line = 6 ; column = 29 ; value ='@'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 119 ; length = 8 line = 6 ; column = 30 ; value ='position'; }
|
||||||
|
{kind = TOKEN_RIGHTPAREN; ; index = 127 ; length = 1 line = 6 ; column = 38 ; value =')'; }
|
||||||
|
{kind = TOKEN_ARROW; ; index = 129 ; length = 2 line = 6 ; column = 40 ; value ='->'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 132 ; length = 6 line = 6 ; column = 43 ; value ='float4'; }
|
||||||
|
{kind = TOKEN_AT; ; index = 139 ; length = 1 line = 6 ; column = 50 ; value ='@'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 140 ; length = 8 line = 6 ; column = 51 ; value ='position'; }
|
||||||
|
{kind = TOKEN_LEFTBRACE; ; index = 149 ; length = 1 line = 6 ; column = 60 ; value ='{'; }
|
||||||
|
{kind = TOKEN_RETURN; ; index = 153 ; length = 6 line = 7 ; column = 0 ; value ='return'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 160 ; length = 3 line = 7 ; column = 7 ; value ='mul'; }
|
||||||
|
{kind = TOKEN_LEFTPAREN; ; index = 163 ; length = 1 line = 7 ; column = 10 ; value ='('; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 164 ; length = 10 line = 7 ; column = 11 ; value ='projection'; }
|
||||||
|
{kind = TOKEN_COMMA; ; index = 174 ; length = 1 line = 7 ; column = 21 ; value =','; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 176 ; length = 3 line = 7 ; column = 23 ; value ='mul'; }
|
||||||
|
{kind = TOKEN_LEFTPAREN; ; index = 179 ; length = 1 line = 7 ; column = 26 ; value ='('; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 180 ; length = 4 line = 7 ; column = 27 ; value ='view'; }
|
||||||
|
{kind = TOKEN_COMMA; ; index = 184 ; length = 1 line = 7 ; column = 31 ; value =','; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 186 ; length = 3 line = 7 ; column = 33 ; value ='pos'; }
|
||||||
|
{kind = TOKEN_RIGHTPAREN; ; index = 189 ; length = 1 line = 7 ; column = 36 ; value =')'; }
|
||||||
|
{kind = TOKEN_RIGHTPAREN; ; index = 190 ; length = 1 line = 7 ; column = 37 ; value =')'; }
|
||||||
|
{kind = TOKEN_SEMICOLON; ; index = 191 ; length = 1 line = 7 ; column = 38 ; value =';'; }
|
||||||
|
{kind = TOKEN_RIGHTBRACE; ; index = 194 ; length = 1 line = 8 ; column = 0 ; value ='}'; }
|
||||||
|
{kind = TOKEN_PIXEL; ; index = 199 ; length = 5 line = 10 ; column = 0 ; value ='pixel'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 205 ; length = 4 line = 10 ; column = 6 ; value ='main'; }
|
||||||
|
{kind = TOKEN_DOUBLECOLON; ; index = 210 ; length = 2 line = 10 ; column = 11 ; value ='::'; }
|
||||||
|
{kind = TOKEN_LEFTPAREN; ; index = 213 ; length = 1 line = 10 ; column = 14 ; value ='('; }
|
||||||
|
{kind = TOKEN_RIGHTPAREN; ; index = 214 ; length = 1 line = 10 ; column = 15 ; value =')'; }
|
||||||
|
{kind = TOKEN_ARROW; ; index = 216 ; length = 2 line = 10 ; column = 17 ; value ='->'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 219 ; length = 6 line = 10 ; column = 20 ; value ='float4'; }
|
||||||
|
{kind = TOKEN_AT; ; index = 226 ; length = 1 line = 10 ; column = 27 ; value ='@'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 227 ; length = 6 line = 10 ; column = 28 ; value ='target'; }
|
||||||
|
{kind = TOKEN_LEFTBRACE; ; index = 234 ; length = 1 line = 10 ; column = 35 ; value ='{'; }
|
||||||
|
{kind = TOKEN_RETURN; ; index = 238 ; length = 6 line = 11 ; column = 0 ; value ='return'; }
|
||||||
|
{kind = TOKEN_IDENTIFIER; ; index = 245 ; length = 5 line = 11 ; column = 7 ; value ='float'; }
|
||||||
|
{kind = TOKEN_LEFTPAREN; ; index = 250 ; length = 1 line = 11 ; column = 12 ; value ='('; }
|
||||||
|
{kind = TOKEN_FLOATLITERAL; ; index = 251 ; length = 3 line = 11 ; column = 13 ; value ='0.5'; }
|
||||||
|
{kind = TOKEN_COMMA; ; index = 254 ; length = 1 line = 11 ; column = 16 ; value =','; }
|
||||||
|
{kind = TOKEN_FLOATLITERAL; ; index = 256 ; length = 3 line = 11 ; column = 18 ; value ='0.5'; }
|
||||||
|
{kind = TOKEN_COMMA; ; index = 259 ; length = 1 line = 11 ; column = 21 ; value =','; }
|
||||||
|
{kind = TOKEN_FLOATLITERAL; ; index = 261 ; length = 3 line = 11 ; column = 23 ; value ='0.5'; }
|
||||||
|
{kind = TOKEN_COMMA; ; index = 264 ; length = 1 line = 11 ; column = 26 ; value =','; }
|
||||||
|
{kind = TOKEN_FLOATLITERAL; ; index = 266 ; length = 3 line = 11 ; column = 28 ; value ='1'; }
|
||||||
|
{kind = TOKEN_RIGHTPAREN; ; index = 269 ; length = 1 line = 11 ; column = 31 ; value =')'; }
|
||||||
|
{kind = TOKEN_SEMICOLON; ; index = 270 ; length = 1 line = 11 ; column = 32 ; value =';'; }
|
||||||
|
{kind = TOKEN_RIGHTBRACE; ; index = 273 ; length = 1 line = 12 ; column = 0 ; value ='}'; }
|
||||||
|
{kind = TOKEN_EOF; ; index = 276 ; length = 0 line = 13 ; column = 0 ; value =''; }
|
||||||
@@ -9,5 +9,8 @@
|
|||||||
{kind = TOKEN_ARROW; ; index = 30 ; length = 2 line = 1 ; column = 30 ; value ='->'; }
|
{kind = TOKEN_ARROW; ; index = 30 ; length = 2 line = 1 ; column = 30 ; value ='->'; }
|
||||||
{kind = TOKEN_IDENTIFIER; ; index = 33 ; length = 3 line = 1 ; column = 33 ; value ='int'; }
|
{kind = TOKEN_IDENTIFIER; ; index = 33 ; length = 3 line = 1 ; column = 33 ; value ='int'; }
|
||||||
{kind = TOKEN_LEFTBRACE; ; index = 37 ; length = 1 line = 1 ; column = 37 ; value ='{'; }
|
{kind = TOKEN_LEFTBRACE; ; index = 37 ; length = 1 line = 1 ; column = 37 ; value ='{'; }
|
||||||
{kind = TOKEN_RIGHTBRACE; ; index = 43 ; length = 1 line = 3 ; column = 0 ; value ='}'; }
|
{kind = TOKEN_RETURN; ; index = 41 ; length = 6 line = 2 ; column = 0 ; value ='return'; }
|
||||||
{kind = TOKEN_EOF; ; index = 46 ; length = 0 line = 4 ; column = 0 ; value =''; }
|
{kind = TOKEN_INTLITERAL; ; index = 48 ; length = 1 line = 2 ; column = 7 ; value ='0'; }
|
||||||
|
{kind = TOKEN_SEMICOLON; ; index = 49 ; length = 1 line = 2 ; column = 8 ; value =';'; }
|
||||||
|
{kind = TOKEN_RIGHTBRACE; ; index = 52 ; length = 1 line = 3 ; column = 0 ; value ='}'; }
|
||||||
|
{kind = TOKEN_EOF; ; index = 55 ; length = 0 line = 4 ; column = 0 ; value =''; }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
test/assign_arithmetic_expression.shd lex
|
test/assign_arithmetic_expression.shd lex
|
||||||
test/basic_property_and_return_value.shd lex
|
test/basic_property_and_return_value.shd lex
|
||||||
test/complicated_computation.shd lex
|
test/complicated_computation.shd lex
|
||||||
|
test/constant_buffer.shd lex
|
||||||
test/empty_struct.shd lex
|
test/empty_struct.shd lex
|
||||||
test/empty_vertex_main.shd lex
|
test/empty_vertex_main.shd lex
|
||||||
test/empty_vertex_main_with_position_parameter.shd lex
|
test/empty_vertex_main_with_position_parameter.shd lex
|
||||||
|
|||||||
@@ -2,4 +2,5 @@
|
|||||||
(fun vertex vs_main -> float4 (@position)
|
(fun vertex vs_main -> float4 (@position)
|
||||||
[(:= pos float4 (@position))]
|
[(:= pos float4 (@position))]
|
||||||
(:= x float 5)
|
(:= x float 5)
|
||||||
(= x 7)))
|
(= x 7)
|
||||||
|
(return pos)))
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
(program
|
(program
|
||||||
(fun vertex vs_main -> int
|
(fun vertex vs_main -> int
|
||||||
[(:= pos float3)]))
|
[(:= pos float3)]
|
||||||
|
(return 0)))
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
test/assign_arithmetic_expression.shd parse
|
test/assign_arithmetic_expression.shd parse
|
||||||
test/basic_property_and_return_value.shd parse
|
test/basic_property_and_return_value.shd parse
|
||||||
test/complicated_computation.shd parse
|
test/complicated_computation.shd parse
|
||||||
|
test/constant_buffer.shd parse
|
||||||
test/empty_struct.shd parse
|
test/empty_struct.shd parse
|
||||||
test/empty_vertex_main.shd parse
|
test/empty_vertex_main.shd parse
|
||||||
test/empty_vertex_main_with_position_parameter.shd parse
|
test/empty_vertex_main_with_position_parameter.shd parse
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
scope (global) [
|
scope (global) [
|
||||||
[vertex__vs_main] : (pos : float4)
|
[vertex__vs_main] : (pos : float4) -> float4
|
||||||
scope (vertex__vs_main) [
|
scope (vertex__vs_main) [
|
||||||
[x] : float
|
[x] : float
|
||||||
[pos] : float4
|
[pos] : float4
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
scope (global) [
|
scope (global) [
|
||||||
[vertex__vs_main] : (pos : float3)
|
[vertex__vs_main] : (pos : float3) -> int
|
||||||
scope (vertex__vs_main) [
|
scope (vertex__vs_main) [
|
||||||
[pos] : float3
|
[pos] : float3
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
test/assign_arithmetic_expression.shd semant
|
test/assign_arithmetic_expression.shd semant
|
||||||
test/basic_property_and_return_value.shd semant
|
test/basic_property_and_return_value.shd semant
|
||||||
test/complicated_computation.shd semant
|
test/complicated_computation.shd semant
|
||||||
|
test/constant_buffer.shd semant
|
||||||
test/empty_struct.shd semant
|
test/empty_struct.shd semant
|
||||||
test/empty_vertex_main.shd semant
|
test/empty_vertex_main.shd semant
|
||||||
test/empty_vertex_main_with_position_parameter.shd semant
|
test/empty_vertex_main_with_position_parameter.shd semant
|
||||||
|
|||||||
Reference in New Issue
Block a user