Added syntax check to Global functions tab in Node editor.

This commit is contained in:
Rodz Labs 2021-09-26 21:28:12 +02:00
parent 1f67e83f24
commit 36d5726b25
5 changed files with 437 additions and 396 deletions

View File

@ -4,9 +4,14 @@ const REGEXS : Array = [
{ type="ignore", regex="^[\\s\\r\\n]+" },
{ type="FLOATCONSTANT", regex="^(\\d*[.])?\\d+([eE][-+]?\\d+)?" },
{ type="IDENTIFIER", regex="^\\$?[\\w_]+" },
{ type="SYMBOLS", regex="^[+-/*)(,{}.]" },
{ type="SYMBOLS", regex="^(\\|\\||\\&\\&|\\^\\^|==)" },
{ type="SYMBOLS", regex="^(<<|>>|&&|\\|\\||^^)=" },
{ type="SYMBOLS", regex="^[+-/*\\%<>!&|^]=" },
{ type="SYMBOLS", regex="^[+-/*=<>)(,;\\{\\}.&|^]" },
]
const KEYWORDS = [ "if", "else", "for", "while", "break", "continue", "return" ]
const TYPES = [ "void", "float", "int", "bool", "vec2", "vec3", "vec4",
"bvec2", "bvec3", "bvec4", "ivec2", "ivec3", "ivec4",
"mat2", "mat3", "mat4", "mat2x2", "mat2x3", "mat2x4",
@ -21,6 +26,12 @@ func create_token(type : String, value, pos_begin : int, pos_end : int) -> Token
match type:
"FLOATCONSTANT":
return .create_token(type, value.to_float(), pos_begin, pos_end)
"IDENTIFIER":
if value in KEYWORDS:
return .create_token(value.to_upper(), null, pos_begin, pos_end)
if value in TYPES:
return .create_token("TYPE", value.to_upper(), pos_begin, pos_end)
return .create_token(type, value, pos_begin, pos_end)
"SYMBOLS":
return .create_token(value, null, pos_begin, pos_end)
_:
@ -28,7 +39,7 @@ func create_token(type : String, value, pos_begin : int, pos_end : int) -> Token
var selection_regex : RegEx
func build_field_selection(t1):
func build_field_selection_test(t1):
if selection_regex == null:
selection_regex = RegEx.new()
selection_regex.compile("[^rgbaxyzw]")

File diff suppressed because it is too large Load Diff

View File

@ -74,14 +74,14 @@ func parse(s : String):
var penultimate_nt : String
while true:
if ! actions[state].has(next_token.type):
return { status="ERROR", pos=next_token.pos_begin }
return { status="ERROR", msg="Unexpected token %s (state %d)" % [ next_token.type, state ], pos=next_token.pos_begin }
var action = actions[state][next_token.type]
match action[0]:
"s":
stack.push_back(StackElement.new(state, next_token))
state = action.right(1).to_int()
if tokens.empty():
return { status="ERROR", pos=next_token.pos_end+1 }
return { status="ERROR", msg="Reached end of file", pos=next_token.pos_end+1 }
next_token = tokens.pop_front()
"r":
var rule : Dictionary = rules[action.right(1).to_int()]
@ -90,13 +90,16 @@ func parse(s : String):
var stack_element : StackElement = stack.pop_back()
state = stack_element.state
reduce_tokens.push_front(stack_element.token)
var pos_begin = reduce_tokens[0].pos_begin
var pos_end = reduce_tokens[reduce_tokens.size()-1].pos_end
var pos_begin = -1
var pos_end = -1
if ! reduce_tokens.empty():
pos_begin = reduce_tokens[0].pos_begin
pos_end = reduce_tokens[reduce_tokens.size()-1].pos_end
var new_token : Token
if has_method(rule.function):
var value = callv(rule.function, reduce_tokens)
if value == null:
return { status="ERROR", pos=next_token.pos_end+1 }
return { status="ERROR", msg="Error while building token", pos=next_token.pos_end+1 }
new_token = Token.new(rule.nonterm, value, pos_begin, pos_end)
elif reduce_tokens.size() == 1:
new_token = reduce_tokens[0]

View File

@ -9,6 +9,8 @@ onready var instance_functions_editor : TextEdit = $"Sizer/Tabs/Instance Functio
onready var includes_editor : LineEdit = $"Sizer/Tabs/Global Functions/Includes/Includes"
onready var global_functions_editor : TextEdit = $"Sizer/Tabs/Global Functions/Functions"
onready var parser = load("res://addons/material_maker/parser/glsl_parser.gd").new()
const ParameterEditor = preload("res://material_maker/windows/node_editor/parameter.tscn")
const InputEditor = preload("res://material_maker/windows/node_editor/input.tscn")
const OutputEditor = preload("res://material_maker/windows/node_editor/output.tscn")
@ -60,10 +62,13 @@ func set_model_data(data) -> void:
includes_editor.text = PoolStringArray(data.includes).join(",")
if data.has("global"):
global_functions_editor.text = data.global
global_functions_editor.clear_undo_history()
if data.has("instance"):
instance_functions_editor.text = data.instance
instance_functions_editor.clear_undo_history()
if data.has("code"):
main_code_editor.text = data.code
main_code_editor.clear_undo_history()
func get_model_data() -> Dictionary:
var data = {
@ -105,6 +110,25 @@ func _on_AddOutput_pressed() -> void:
add_item(output_list, OutputEditor)
output_list.update_up_down_buttons()
# Global functions
var globals_error_line = -1
func _on_Functions_text_changed():
var text : String = global_functions_editor.text
if globals_error_line != -1:
global_functions_editor.set_line_as_safe(globals_error_line, false)
var result = parser.parse(global_functions_editor.text)
if result is Dictionary and result.has("status"):
match result.status:
"OK":
globals_error_line = -1
_:
globals_error_line = text.substr(0, result.pos).count("\n")
global_functions_editor.set_line_as_safe(globals_error_line, true)
# OK/Apply/Cancel buttons
func _on_Apply_pressed() -> void:
emit_signal("node_changed", get_model_data())
@ -114,3 +138,5 @@ func _on_OK_pressed() -> void:
func _on_Cancel_pressed() -> void:
queue_free()

View File

@ -219,7 +219,9 @@ margin_bottom = -36.0
mouse_default_cursor_shape = 0
size_flags_vertical = 3
custom_fonts/font = SubResource( 3 )
custom_colors/safe_line_number_color = Color( 1, 0, 0, 1 )
custom_colors/brace_mismatch_color = Color( 1, 0, 0, 1 )
custom_colors/executing_line_color = Color( 1, 0, 0, 1 )
syntax_highlighting = true
show_line_numbers = true
@ -249,9 +251,11 @@ margin_right = 218.0
margin_bottom = 20.0
rect_min_size = Vector2( 70, 0 )
text = "Cancel"
[connection signal="pressed" from="Sizer/Tabs/General/Parameters/Sizer/AddParameter" to="." method="_on_AddParameter_pressed"]
[connection signal="pressed" from="Sizer/Tabs/General/Inputs/Sizer/AddInput" to="." method="_on_AddInput_pressed"]
[connection signal="pressed" from="Sizer/Tabs/Outputs/Outputs/Sizer/AddOutput" to="." method="_on_AddOutput_pressed"]
[connection signal="text_changed" from="Sizer/Tabs/Global Functions/Functions" to="." method="_on_Functions_text_changed"]
[connection signal="pressed" from="Sizer/HBoxContainer/Apply" to="." method="_on_Apply_pressed"]
[connection signal="pressed" from="Sizer/HBoxContainer/OK" to="." method="_on_OK_pressed"]
[connection signal="pressed" from="Sizer/HBoxContainer/Cancel" to="." method="_on_Cancel_pressed"]