EOI : lecture 12 compelte

This commit is contained in:
Edward R. Gonzalez 2022-07-24 09:50:38 -04:00
parent bd6e39ecdd
commit a6c99fcfa6
3 changed files with 131 additions and 21 deletions

View File

@ -46,6 +46,9 @@ func eval( ast ):
var result = eval( ast.arg(index) ) var result = eval( ast.arg(index) )
if result != null: if result != null:
if typeof(result) == TYPE_OBJECT && result.get_class() == "ASTNode":
return JSON.print(result.to_SExpression())
return String( result ) return String( result )
else: else:
return null return null
@ -84,6 +87,37 @@ func eval( ast ):
Env.define(symbol, fnDef) Env.define(symbol, fnDef)
return Env.lookup(symbol) return Env.lookup(symbol)
NType.fn_Lambda:
var fnDef = \
[
ast.arg(1), # Parameters
ast.arg(2), # Body
self # Closure (Environment capture)
]
return fnDef
NType.fn_IIL:
var params = ast.arg(1).arg(1)
var body = ast.arg(1).arg(2)
var fnEva = get_script().new( self, EvalOut )
if params.type() != NType.empty:
var index = 1
while index <= params.num_args():
var paramVal = eval( ast.arg(index + 1) )
fnEva.Env.define(params.arg(index), paramVal )
index += 1
var result
var index = 1;
while index <= body.num_args() :
result = fnEva.eval( body.arg( index ) )
index += 1
return result
NType.identifier : NType.identifier :
return eval_Lookup( ast ) return eval_Lookup( ast )
@ -172,7 +206,14 @@ func eval_Func( ast ):
fnEva.Env.define(params.arg(index), paramVal ) fnEva.Env.define(params.arg(index), paramVal )
index += 1 index += 1
return fnEva.eval( body ) var result
var index = 1;
while index <= body.num_args() :
result = fnEva.eval( body.arg( index ) )
index += 1
return result
func eval_Numeric( ast ): func eval_Numeric( ast ):
if ast.type() == NType.op_Add: if ast.type() == NType.op_Add:

View File

@ -31,6 +31,7 @@ const TType : Dictionary = \
def_While = "Expression While", def_While = "Expression While",
def_Var = "Variable Declaration", def_Var = "Variable Declaration",
def_Func = "Function Declaration", def_Func = "Function Declaration",
def_Lambda = "Lambda Declaration",
literal_Number = "Literal: Number", literal_Number = "Literal: Number",
literal_String = "Literal: String", literal_String = "Literal: String",
@ -58,6 +59,7 @@ const Spec : Dictionary = \
TType.def_While : "start \"while\"", TType.def_While : "start \"while\"",
TType.def_Var : "start \"var\"", TType.def_Var : "start \"var\"",
TType.def_Func : "start \"def\"", TType.def_Func : "start \"def\"",
TType.def_Lambda : "start \"lambda\"",
TType.literal_Number : \ TType.literal_Number : \
"""start """start

View File

@ -46,7 +46,10 @@ const NType = \
fn_Print = "Print", fn_Print = "Print",
fn_User = "User Function", fn_User = "User Function",
fn_Lambda = "Lambda Function",
fn_IIL = "Lambda Function Immediate Invocation",
fn_Params = "Function Parameters", fn_Params = "Function Parameters",
fn_Body = "Function Body",
identifier = "Identifier", identifier = "Identifier",
variable = "Variable" variable = "Variable"
@ -55,6 +58,10 @@ const NType = \
class ASTNode: class ASTNode:
var Data : Array var Data : Array
func get_class() :
return "ASTNode"
func add_Expr( expr ): func add_Expr( expr ):
Data.append(expr) Data.append(expr)
@ -99,6 +106,9 @@ class ASTNode:
result.append( array_Serialize( entry, fn_objSerializer )) result.append( array_Serialize( entry, fn_objSerializer ))
elif typeof(entry) == TYPE_OBJECT : elif typeof(entry) == TYPE_OBJECT :
if entry.get_class() == "Eva":
result.append(entry)
else:
fn_objSerializer.set_instance(entry) fn_objSerializer.set_instance(entry)
result.append( fn_objSerializer.call_func() ) result.append( fn_objSerializer.call_func() )
@ -151,7 +161,7 @@ func parse():
node.add_Expr( parse_Identifier() ) node.add_Expr( parse_Identifier() )
elif NextToken.is_Literal(): elif NextToken.is_Literal():
node.Add_Expr( parse_Literal() ) node.add_Expr( parse_Literal() )
return node return node
@ -170,6 +180,8 @@ func parse_Expression():
node = parse_Variable() node = parse_Variable()
TType.def_Func: TType.def_Func:
node = parse_fn_User() node = parse_fn_User()
TType.def_Lambda:
node = parse_fn_Lambda()
TType.fn_Print: TType.fn_Print:
node = parse_fn_Print() node = parse_fn_Print()
TType.op_Assgin: TType.op_Assgin:
@ -180,6 +192,8 @@ func parse_Expression():
node = parse_op_Relational() node = parse_op_Relational()
TType.identifier: TType.identifier:
node = parse_op_Fn() node = parse_op_Fn()
TType.def_Start:
node = parse_fn_IIL()
var arg = 1 var arg = 1
while NextToken.Type != TType.def_End: while NextToken.Type != TType.def_End:
@ -267,7 +281,60 @@ func parse_fn_User():
eat(TType.def_End) eat(TType.def_End)
var \
bNode = ASTNode.new()
bNode.set_Type(NType.fn_Body)
while NextToken.Type != TType.def_End:
bNode.add_Expr( parse_Expression() )
node.add_Expr( pNode ) node.add_Expr( pNode )
node.add_Expr( bNode )
return node
func parse_fn_Lambda():
var \
node = ASTNode.new()
node.set_Type(NType.fn_Lambda)
eat(TType.def_Lambda)
# Parameters
var \
pNode = ASTNode.new()
pNode.set_Type(NType.fn_Params)
eat(TType.def_Start)
while NextToken.Type != TType.def_End:
check( NextToken.Type == TType.identifier,
String("Parser - parse_op_Assign: NextToken should have been identifier, Type: {type} Value: {value}") \
.format({"type" : NextToken.Type, "value" : NextToken.Value })
)
pNode.add_TokenValue(NextToken)
eat(TType.identifier)
eat(TType.def_End)
var \
bNode = ASTNode.new()
bNode.set_Type(NType.fn_Body)
while NextToken.Type != TType.def_End:
bNode.add_Expr( parse_Expression() )
node.add_Expr( pNode )
node.add_Expr( bNode )
return node
func parse_fn_IIL():
var \
node = ASTNode.new()
node.set_Type(NType.fn_IIL)
# Lambda
node.add_Expr( parse_Expression() )
return node return node