mirror of
https://github.com/Ed94/LangStudies.git
synced 2024-11-10 04:14:53 -08:00
EOI: Lecture 8 complete
This commit is contained in:
parent
e120749a7e
commit
ba53395fc7
@ -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
|
||||||
|
@ -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\"",
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user