EOI: Lecture 8 complete

This commit is contained in:
Edward R. Gonzalez 2022-07-24 04:36:18 -04:00
parent e120749a7e
commit ba53395fc7
3 changed files with 139 additions and 54 deletions

View File

@ -31,49 +31,81 @@ func _init(parent, evalOut):
Parent = parent Parent = parent
func eval( ast ): func eval( ast ):
if ast.type() == NType.program : match ast.type():
var index = 1; NType.program :
while index < ast.num_args(): var index = 1;
eval( ast.arg(index) ) while index < ast.num_args():
index += 1 eval( ast.arg(index) )
index += 1
var result = eval( ast.arg(index) ) var result = eval( ast.arg(index) )
if result != null: if result != null:
return String( result ) return String( result )
else: else:
return null return null
elif ast.type() == NType.block : NType.block :
return eval_Block( ast ) return eval_Block( ast )
elif ast.type() == NType.identifier : NType.conditional:
var identifier = ast.arg(1) var condition = eval( ast.arg(1) )
if Parent != null && !Env.has( identifier): if condition:
return Parent.Env.lookup( identifier ) # consequent
return eval( ast.arg(2) )
return Env.lookup( identifier ) # Alternate
if ast.num_args() > 2:
return eval( ast.arg(3))
elif ast.type() == NType.fn_Print : NType.expr_While:
return eval_Print( ast ) var result
elif ast.type() == NType.op_Assign : while eval( ast.arg(1) ):
var symbol = ast.arg(1) result = eval( ast.arg(2) )
var value = eval( ast.arg(2) )
if Parent != null && !Env.has( symbol): return result
return Parent.Env.set( symbol, value )
return Env.set( symbol, value ) NType.identifier :
var identifier = ast.arg(1)
elif ast.type() == NType.variable : if Parent != null && !Env.has( identifier):
var symbol = ast.arg(1) return Parent.Env.lookup( identifier )
var value = eval( ast.arg(2) )
Env.define_Var(symbol, value) return Env.lookup( identifier )
return value
elif ast.is_Number() : 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) ) return float( ast.arg(1) )
elif ast.is_String() : elif ast.is_String() :
@ -81,10 +113,6 @@ func eval( ast ):
return eval_Numeric( ast ) 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 ): func eval_Block( ast ):
var eva_Block = get_script().new( self, EvalOut ) var eva_Block = get_script().new( self, EvalOut )
@ -134,6 +162,10 @@ func eval_Numeric( ast ):
return result return result
var msgT = "eval - Unimplemented: {ast}"
var msg = msgT.format({"ast" : JSON.print(ast.to_SExpression(), "\t") })
throw(msg)
func eval_Print( ast ): func eval_Print( ast ):
EvalOut.text += "\n" + String( eval( ast.arg(1) ) ) EvalOut.text += "\n" + String( eval( ast.arg(1) ) )
return null return null

View File

@ -27,13 +27,16 @@ const TType : Dictionary = \
def_Block = "Expression Block Start", def_Block = "Expression Block Start",
def_Start = "Expression Start", def_Start = "Expression Start",
def_End = "Expression End", def_End = "Expression End",
def_Var = "Variable", def_Cond = "Expression Conditional",
def_While = "Expression While",
def_Var = "Variable Declaration",
literal_Number = "Literal: Number", literal_Number = "Literal: Number",
literal_String = "Literal: String", literal_String = "Literal: String",
op_Assgin = "Assignment", op_Assgin = "Assignment",
op_Numeric = "op_Numeric", op_Numeric = "op_Numeric",
op_Relational = "op_Relational",
fn_Print = "Print", fn_Print = "Print",
@ -50,6 +53,8 @@ const Spec : Dictionary = \
TType.def_Block : "start \"begin\"", TType.def_Block : "start \"begin\"",
TType.def_Start : "start \\(", TType.def_Start : "start \\(",
TType.def_End : "start \\)", TType.def_End : "start \\)",
TType.def_Cond : "start \"if\"",
TType.def_While : "start \"while\"",
TType.def_Var : "start \"var\"", TType.def_Var : "start \"var\"",
TType.literal_Number : \ TType.literal_Number : \
@ -60,8 +65,9 @@ const Spec : Dictionary = \
""", """,
TType.literal_String : "start \\\" !set( \\\" ).repeat(0-) \\\" ", TType.literal_String : "start \\\" !set( \\\" ).repeat(0-) \\\" ",
TType.op_Assgin : "start \"set\"", TType.op_Assgin : "start \"set\"",
TType.op_Numeric : "start set(+ \\- * /)", TType.op_Numeric : "start set(+ \\- * /)",
TType.op_Relational : "start set(> <) =.repeat(0-1)",
TType.fn_Print : "start \"print\"", TType.fn_Print : "start \"print\"",

View File

@ -23,15 +23,23 @@ const NType = \
block = "Scope Block", block = "Scope Block",
conditional = "Conditional",
expr_While = "Expression While",
literal_Number = "Literal: Number", literal_Number = "Literal: Number",
literal_String = "Literal: String", literal_String = "Literal: String",
op_Assign = "Assignment", op_Assign = "Assignment",
op_Add = "+", op_Add = "+",
op_Sub = "-", op_Sub = "-",
op_Mult = "*", op_Mult = "*",
op_Div = "/", op_Div = "/",
op_Greater = ">",
op_GreaterEqual = ">=",
op_Lesser = "<",
op_LesserEqual = "<=",
fn_Print = "Print", fn_Print = "Print",
@ -149,6 +157,10 @@ func parse_Expression():
match NextToken.Type : match NextToken.Type :
TType.def_Block: TType.def_Block:
node = parse_Block() node = parse_Block()
TType.def_Cond:
node = parse_ConditionalIf()
TType.def_While:
node = parse_While()
TType.def_Var: TType.def_Var:
node = parse_Variable() node = parse_Variable()
TType.fn_Print: TType.fn_Print:
@ -157,6 +169,9 @@ func parse_Expression():
node = parse_op_Assign() node = parse_op_Assign()
TType.op_Numeric: TType.op_Numeric:
node = parse_op_Numeric() node = parse_op_Numeric()
TType.op_Relational:
node = parse_op_Relational()
var arg = 1 var arg = 1
while NextToken.Type != TType.def_End: while NextToken.Type != TType.def_End:
@ -179,6 +194,20 @@ func parse_Block():
return node 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(): func parse_Variable():
var \ var \
node = ASTNode.new() node = ASTNode.new()
@ -260,6 +289,23 @@ func parse_op_Numeric():
return node 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(): func parse_Literal():
var node = ASTNode.new() var node = ASTNode.new()
@ -283,3 +329,4 @@ func _init(lexer, errorOut) :
Lexer = lexer Lexer = lexer
NextToken = Lexer.next_Token() NextToken = Lexer.next_Token()