public LinkedList <Value> BodyExpression; // (lambda (...) <...>) public AstLambda(Syntax syntax, Syntax keyword, Environment environment, LinkedList <Value> expression) : base(syntax) { ArgList = environment.ToAstArray(); BodyExpression = expression; if (keyword.GetDatum() == Symbol.LAMBDA) { Keyword = keyword; } else { Keyword = new Syntax(Symbol.LAMBDA, keyword.Location); } }
public static Value GetDatum(Syntax syn) { return(syn.GetDatum()); }
// aka: x public static AST ExpandIdentifier(Syntax syntax, Environment env) { if (!syntax.IsIdentifier) { throw SchemeError.SyntaxError("ast-builder-expand-identifier", "expected identifier", syntax); } var varname = syntax.GetDatum().AsSymbol(); // Check and expand some of literals if (varname == Symbol.NULL) { return(new AstLiteral(syntax)); } // Find the variable in ast environment int envIdx = 0; var binding = env.LookupAstRecursively(varname, ref envIdx); if (binding == null) { // If variable is not found designate it as global variable var localIdx = env.Define(varname, new GlobalBinding(syntax)); return(new AstReference(syntax, AstReferenceType.Global, localIdx)); } else { if (envIdx == 0) { // local variable reference return(new AstReference(syntax, AstReferenceType.Local, binding.VarIdx, 0, 0)); } else { // up-value reference if (binding is GlobalBinding || !binding.environment.IsLexical) { // global variable var localIdx = env.Define(varname, new GlobalBinding(syntax)); return(new AstReference(syntax, AstReferenceType.Global, localIdx)); } else if (binding is LocalBinding || binding is ArgumentBinding) { // up value to local variable var localIdx = env.Define(varname, new UpBinding(syntax, envIdx, binding.VarIdx)); return(new AstReference(syntax, AstReferenceType.UpValue, localIdx, envIdx, binding.VarIdx)); } else if (binding is UpBinding) { // upValue to other upValue var upBinding = binding as UpBinding; var nEnvIdx = upBinding.UpEnvIdx + envIdx; var nVarIdx = upBinding.UpVarIdx; var localIdx = env.Define(varname, new UpBinding(syntax, nEnvIdx, nVarIdx)); return(new AstReference(syntax, AstReferenceType.UpValue, localIdx, nEnvIdx, nVarIdx)); } else { throw new SystemException(); } } } }