diff --git a/App/EoI/Scripts/Eva.gd b/App/EoI/Scripts/Eva.gd index 57c5e1d..0a32c89 100644 --- a/App/EoI/Scripts/Eva.gd +++ b/App/EoI/Scripts/Eva.gd @@ -31,59 +31,87 @@ func _init(parent, evalOut): Parent = parent func eval( ast ): - if ast.type() == NType.program : - var index = 1; - while index < ast.num_args(): - eval( ast.arg(index) ) - index += 1 - - var result = eval( ast.arg(index) ) - if result != null: - return String( result ) - else: - return null + match ast.type(): + NType.program : + var index = 1; + while index < ast.num_args(): + eval( ast.arg(index) ) + index += 1 + + var result = eval( ast.arg(index) ) + if result != null: + return String( result ) + else: + return null - elif ast.type() == NType.block : - return eval_Block( ast ) - - elif ast.type() == NType.identifier : - var identifier = ast.arg(1) - - if Parent != null && !Env.has( identifier): - return Parent.Env.lookup( identifier ) - - return Env.lookup( identifier ) - - elif ast.type() == NType.fn_Print : - return eval_Print( ast ) - - elif ast.type() == NType.op_Assign : - var symbol = ast.arg(1) - var value = eval( ast.arg(2) ) - - if Parent != null && !Env.has( symbol): - return Parent.Env.set( symbol, value ) - - return Env.set( symbol, value ) - - elif ast.type() == NType.variable : - var symbol = ast.arg(1) - var value = eval( ast.arg(2) ) + NType.block : + return eval_Block( ast ) - Env.define_Var(symbol, value) - return value + NType.conditional: + var condition = eval( ast.arg(1) ) + + if condition: + # consequent + return eval( ast.arg(2) ) + + # Alternate + if ast.num_args() > 2: + return eval( ast.arg(3)) + + NType.expr_While: + var result + + while eval( ast.arg(1) ): + result = eval( ast.arg(2) ) + + return result - elif ast.is_Number() : + NType.identifier : + var identifier = ast.arg(1) + + if Parent != null && !Env.has( identifier): + return Parent.Env.lookup( identifier ) + + return Env.lookup( identifier ) + + NType.op_Assign : + var symbol = ast.arg(1) + var value = eval( ast.arg(2) ) + + if Parent != null && !Env.has( symbol): + return Parent.Env.set( symbol, value ) + + return Env.set( symbol, value ) + + NType.op_Greater: + return eval( ast.arg(1) ) > eval( ast.arg(2) ) + + NType.op_Lesser: + return eval( ast.arg(1) ) < eval( ast.arg(2) ) + + NType.op_GreaterEqual: + return eval( ast.arg(1) ) >= eval( ast.arg(2) ) + + NType.op_LesserEqual: + return eval( ast.arg(1) ) <= eval( ast.arg(2) ) + + NType.fn_Print : + return eval_Print( ast ) + + NType.variable : + var symbol = ast.arg(1) + var value = eval( ast.arg(2) ) + + Env.define_Var(symbol, value) + return value + + if ast.is_Number() : return float( ast.arg(1) ) 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 ) @@ -133,6 +161,10 @@ func eval_Numeric( ast ): result += 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) ) ) diff --git a/App/EoI/Scripts/Lexer.gd b/App/EoI/Scripts/Lexer.gd index 6b235a5..bb2e3d4 100644 --- a/App/EoI/Scripts/Lexer.gd +++ b/App/EoI/Scripts/Lexer.gd @@ -27,13 +27,16 @@ const TType : Dictionary = \ def_Block = "Expression Block Start", def_Start = "Expression Start", def_End = "Expression End", - def_Var = "Variable", + def_Cond = "Expression Conditional", + def_While = "Expression While", + def_Var = "Variable Declaration", literal_Number = "Literal: Number", literal_String = "Literal: String", - op_Assgin = "Assignment", - op_Numeric = "op_Numeric", + op_Assgin = "Assignment", + op_Numeric = "op_Numeric", + op_Relational = "op_Relational", fn_Print = "Print", @@ -50,6 +53,8 @@ const Spec : Dictionary = \ TType.def_Block : "start \"begin\"", TType.def_Start : "start \\(", TType.def_End : "start \\)", + TType.def_Cond : "start \"if\"", + TType.def_While : "start \"while\"", TType.def_Var : "start \"var\"", TType.literal_Number : \ @@ -60,8 +65,9 @@ const Spec : Dictionary = \ """, TType.literal_String : "start \\\" !set( \\\" ).repeat(0-) \\\" ", - TType.op_Assgin : "start \"set\"", - TType.op_Numeric : "start set(+ \\- * /)", + TType.op_Assgin : "start \"set\"", + TType.op_Numeric : "start set(+ \\- * /)", + TType.op_Relational : "start set(> <) =.repeat(0-1)", TType.fn_Print : "start \"print\"", diff --git a/App/EoI/Scripts/Parser.gd b/App/EoI/Scripts/Parser.gd index 7a0be78..dbc328d 100644 --- a/App/EoI/Scripts/Parser.gd +++ b/App/EoI/Scripts/Parser.gd @@ -23,15 +23,23 @@ const NType = \ block = "Scope Block", + conditional = "Conditional", + expr_While = "Expression While", + literal_Number = "Literal: Number", literal_String = "Literal: String", op_Assign = "Assignment", - op_Add = "+", - op_Sub = "-", - op_Mult = "*", - op_Div = "/", + op_Add = "+", + op_Sub = "-", + op_Mult = "*", + op_Div = "/", + + op_Greater = ">", + op_GreaterEqual = ">=", + op_Lesser = "<", + op_LesserEqual = "<=", fn_Print = "Print", @@ -149,6 +157,10 @@ func parse_Expression(): match NextToken.Type : TType.def_Block: node = parse_Block() + TType.def_Cond: + node = parse_ConditionalIf() + TType.def_While: + node = parse_While() TType.def_Var: node = parse_Variable() TType.fn_Print: @@ -157,6 +169,9 @@ func parse_Expression(): node = parse_op_Assign() TType.op_Numeric: node = parse_op_Numeric() + TType.op_Relational: + node = parse_op_Relational() + var arg = 1 while NextToken.Type != TType.def_End: @@ -179,6 +194,20 @@ func parse_Block(): return node +func parse_ConditionalIf(): + 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) + return node + func parse_Variable(): var \ node = ASTNode.new() @@ -242,7 +271,7 @@ func parse_op_Assign(): node.add_Expr( parse_Expression() ) return node - + func parse_op_Numeric(): var node = ASTNode.new() @@ -260,6 +289,23 @@ func parse_op_Numeric(): return node +func parse_op_Relational(): + var node = ASTNode.new() + + match NextToken.Value: + NType.op_Greater: + node.set_Type(NType.op_Greater) + NType.op_Lesser: + node.set_Type(NType.op_Lesser) + NType.op_GreaterEqual: + node.set_Type(NType.op_GreaterEqual) + NType.op_LesserEqual: + node.set_Type(NType.op_LesserEqual) + + eat(TType.op_Relational) + + return node + func parse_Literal(): var node = ASTNode.new() @@ -283,3 +329,4 @@ func _init(lexer, errorOut) : Lexer = lexer NextToken = Lexer.next_Token() +