Пример #1
0
        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);
            }
        }
Пример #2
0
 public static Value GetDatum(Syntax syn)
 {
     return(syn.GetDatum());
 }
Пример #3
0
        // 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();
                    }
                }
            }
        }