diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..44326cc --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "GDScript Godot", + "type": "godot", + "request": "launch", + "project": "${workspaceFolder}/App", + "port": 6007, + "address": "127.0.0.1", + "launch_game_instance": true, + "launch_scene": false + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index b3667e2..a1127c5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "editor.formatOnType": true + "editor.formatOnType": true, + "godot_tools.editor_path": "p:\\Study\\LangStudies\\Engine\\gd\\bin\\godot.windows.opt.tools.64.exe" } \ No newline at end of file diff --git a/App/EoI/Scripts/EoI_Viewer.gd b/App/EoI/Scripts/EoI_Viewer.gd index 941bd84..0abea37 100644 --- a/App/EoI/Scripts/EoI_Viewer.gd +++ b/App/EoI/Scripts/EoI_Viewer.gd @@ -43,7 +43,7 @@ func clearBtn_pressed(): func backBtn_pressed(): queue_free() - + func _ready(): Eva = SEva.new(null, Output) diff --git a/App/EoI/Scripts/Eva.gd b/App/EoI/Scripts/Eva.gd index dae36a4..0f50c3b 100644 --- a/App/EoI/Scripts/Eva.gd +++ b/App/EoI/Scripts/Eva.gd @@ -66,6 +66,16 @@ func eval( ast ): # Alternate if ast.num_args() > 2: return eval( ast.arg(3)) + + NType.expr_Switch: + var index = 1 + while ast.arg(index).is_op_Relation(): + if eval( ast.arg(index) ): + return eval( ast.arg(index + 1) ) + + index += 2 + + return eval( ast.arg(index) ) NType.expr_While : var result @@ -74,6 +84,20 @@ func eval( ast ): result = eval( ast.arg(2) ) return result + + NType.expr_For: + var forEva = get_script().new( self, EvalOut ) + + forEva.eval( ast.arg(1) ) + + var index = 3; var result + while forEva.eval( ast.arg(2) ) : + result = forEva.eval( ast.arg(index) ) + index += 1 + if index > ast.num_args() : + index = 3 + + return result NType.fn_User : var symbol = ast.arg(1) @@ -120,13 +144,55 @@ func eval( ast ): NType.identifier : return eval_Lookup( ast ) - NType.op_Assign : return eval_Assign( ast ) - NType.op_Fn: return eval_Func( ast ) + NType.op_Add: + var result = 0.0; var index = 1 + + while index <= ast.num_args(): + result += eval( ast.arg(index) ) + index += 1 + + return result + + NType.op_Sub: + if ast.num_args() < 2: + return -eval( ast.arg(1) ) + + var result = eval( ast.arg(1) ); var index = 2 + + while index <= ast.num_args(): + result -= eval( ast.arg(index) ) + index += 1 + + return result + + NType.op_Mult: + var result = 1.0; var index = 1 + + while index <= ast.num_args(): + result *= eval( ast.arg(index) ) + index += 1 + + return result + + NType.op_Div: + var result = eval( ast.arg(1) ); var index = 2 + + while index <= ast.num_args(): + result /= eval( ast.arg(index) ) + index += 1 + + return result + + NType.op_Increment: + return eval( ast.arg(1) ) + 1 + NType.op_Decrement: + return eval( ast.arg(1) ) - 1 + NType.op_Greater: return eval( ast.arg(1) ) > eval( ast.arg(2) ) NType.op_Lesser: @@ -160,8 +226,10 @@ func eval( ast ): elif ast.is_String() : return ast.string() - - return eval_Numeric( ast ) + + var msgT = "eval - Unimplemented: {ast}" + var msg = msgT.format({"ast" : JSON.print(ast.to_SExpression(), "\t") }) + throw(msg) func eval_Block( ast ): var eva_Block = get_script().new( self, EvalOut ) @@ -219,51 +287,7 @@ func eval_Func( ast ): index += 1 return result - -func eval_Numeric( ast ): - if ast.type() == NType.op_Add: - var result = 0.0; var index = 1 - - while index <= ast.num_args(): - result += eval( ast.arg(index) ) - index += 1 - - return result - - if ast.type() == NType.op_Sub: - if ast.num_args() < 2: - return -eval( ast.arg(1) ) - - var result = eval( ast.arg(1) ); var index = 2 - - while index <= ast.num_args(): - result -= eval( ast.arg(index) ) - index += 1 - - return result - - if ast.type() == NType.op_Mult: - var result = 1.0; var index = 1 - - while index <= ast.num_args(): - result *= eval( ast.arg(index) ) - index += 1 - - return result - - if ast.type() == NType.op_Div: - var result = eval( ast.arg(1) ); var index = 2 - - while index <= ast.num_args(): - result /= eval( ast.arg(index) ) - index += 1 - - return result - - var msgT = "eval - Unimplemented: {ast}" - var msg = msgT.format({"ast" : JSON.print(ast.to_SExpression(), "\t") }) - throw(msg) - + func eval_Print( ast ): EvalOut.text += "\n" + String( eval( ast.arg(1) ) ) return null diff --git a/App/EoI/Scripts/Lexer.gd b/App/EoI/Scripts/Lexer.gd index 4745ce2..6cc427d 100644 --- a/App/EoI/Scripts/Lexer.gd +++ b/App/EoI/Scripts/Lexer.gd @@ -28,7 +28,9 @@ const TType : Dictionary = \ def_End = "Expression End", def_Block = "Expression Block Start", def_Cond = "Expression Conditional", + def_Switch = "Expresssion Switch", def_While = "Expression While", + def_For = "Expression For", def_Var = "Variable Declaration", def_Func = "Function Declaration", def_Lambda = "Lambda Declaration", @@ -57,7 +59,9 @@ const Spec : Dictionary = \ TType.def_End : "start \\)", TType.def_Block : "start \"begin\"", TType.def_Cond : "start \"if\"", + TType.def_Switch : "start \"switch\"", TType.def_While : "start \"while\"", + TType.def_For : "start \"for\"", TType.def_Var : "start \"var\"", TType.def_Func : "start \"def\"", TType.def_Lambda : "start \"lambda\"", @@ -71,7 +75,7 @@ const Spec : Dictionary = \ TType.literal_String : "start \\\" !set( \\\" ).repeat(0-) \\\" ", TType.op_Assgin : "start \"set\"", - TType.op_Numeric : "start set(+ \\- * /)", + TType.op_Numeric : "start set(+ \\- * /) set(+ \\-).repeat(0-1)", TType.op_Relational : "start set(> <) =.repeat(0-1)", TType.op_Equality : "start \\!.repeat(0-1) =", diff --git a/App/EoI/Scripts/Parser.gd b/App/EoI/Scripts/Parser.gd index 0d12193..b926bf1 100644 --- a/App/EoI/Scripts/Parser.gd +++ b/App/EoI/Scripts/Parser.gd @@ -26,7 +26,9 @@ const NType = \ block = "Scope Block", conditional = "Conditional", + expr_Switch = "Expression Switch", expr_While = "Expression While", + expr_For = "Expression For", literal_Number = "Literal: Number", literal_String = "Literal: String", @@ -34,10 +36,12 @@ const NType = \ op_Assign = "Assignment", op_Fn = "Function Call", - op_Add = "+", - op_Sub = "-", - op_Mult = "*", - op_Div = "/", + op_Add = "+", + op_Sub = "-", + op_Mult = "*", + op_Div = "/", + op_Increment = "++", + op_Decrement = "--", op_Greater = ">", op_GreaterEqual = ">=", @@ -63,7 +67,6 @@ class ASTNode: func get_class() : return "ASTNode" - func add_Expr( expr ): Data.append(expr) @@ -82,12 +85,24 @@ class ASTNode: func type(): return Data[0] + func is_op_Relation(): + match type(): + NType.op_Greater: return true + NType.op_Lesser: return true + NType.op_GreaterEqual: return true + NType.op_LesserEqual: return true + NType.op_Equal: return true + NType.op_NotEqual: return true + _: return false + func is_op_Numeric(): match type(): NType.op_Add: return true NType.op_Sub: return true NType.op_Mult: return true NType.op_Div: return true + NType.op_Increment: return true + NType.op_Decrement: return true _: return false func is_Number(): @@ -173,11 +188,15 @@ func parse_Expression(): match NextToken.Type : TType.def_Block: - node = parse_Block() + node = parse_Simple(TType.def_Block, NType.block) TType.def_Cond: - node = parse_ConditionalIf() + node = parse_Simple(TType.def_cond, NType.conditional) + TType.def_Switch: + node = parse_Switch() TType.def_While: - node = parse_While() + node = parse_Simple(TType.def_While, NType.expr_While) + TType.def_For: + node = parse_Simple(TType.def_For, NType.expr_For) TType.def_Var: node = parse_Variable() TType.def_Func: @@ -185,7 +204,7 @@ func parse_Expression(): TType.def_Lambda: node = parse_fn_Lambda() TType.fn_Print: - node = parse_fn_Print() + node = parse_Simple(TType.fn_Print, NType.fn_Print) TType.op_Assgin: node = parse_op_Assign() TType.op_Numeric: @@ -205,7 +224,6 @@ func parse_Expression(): TType.def_Start: node = parse_fn_IIL() - var arg = 1 while NextToken.Type != TType.def_End: if NextToken.Type == TType.def_Start: node.add_Expr( parse_Expression() ) @@ -222,26 +240,20 @@ func parse_Expression(): return node -func parse_Block(): +func parse_Simple(tType, nType): var \ node = ASTNode.new() - node.set_Type(NType.block) - eat(TType.def_Block) + node.set_Type(nType) + eat(tType) return node - -func parse_ConditionalIf(): + +func parse_Switch(): var \ node = ASTNode.new() - node.set_Type(NType.conditional) - eat(TType.def_Cond) - return node - -func parse_While(): - var \ - node = ASTNode.new() - node.set_Type(NType.expr_While) - eat(TType.def_While) + node.set_Type(NType.expr_Switch) + eat(TType.def_Switch) + return node func parse_Variable(): @@ -358,15 +370,6 @@ func parse_Identifier(): return node -func parse_fn_Print(): - var \ - node = ASTNode.new() - node.set_Type(NType.fn_Print) - - eat(TType.fn_Print) - - return node - func parse_op_Assign(): var \ node = ASTNode.new() @@ -402,6 +405,10 @@ func parse_op_Numeric(): node.set_Type(NType.op_Mult) NType.op_Div: node.set_Type(NType.op_Div) + NType.op_Increment: + node.set_Type(NType.op_Increment) + NType.op_Decrement: + node.set_Type(NType.op_Decrement) eat(TType.op_Numeric) diff --git a/Engine/gd b/Engine/gd index 32ef964..270f5a3 160000 --- a/Engine/gd +++ b/Engine/gd @@ -1 +1 @@ -Subproject commit 32ef964b0f7d4e18a919e904988727b3ed775901 +Subproject commit 270f5a3bd1aa3d2f98eeaaae9e36085c9b7df8ef