예제 #1
0
        public void CheckVariables()
        {
            string context = null;

            for (AnalysisScope sc = this; sc != null; sc = sc.Parent)
            {
                if (sc.IsLambda && sc.Name != null)
                {
                    context = sc.Name;
                    break;
                }
            }

            foreach (var v in Variables)
            {
                if (v.Ignorable)
                {
                }
                else if (!v.Referenced)
                {
                    if (!v.Key.SuppressWarnings && !v.Ignore)
                    {
                        PrintWarning(context, "unreferenced variable", v.Key);
                    }
                }
                else if (!v.Initialized && !v.Assigned)
                {
                    PrintWarning(context, "uninitialized variable", v.Key);
                }
            }
        }
예제 #2
0
        public static Cons MacroExpand1(object expr, AnalysisScope env)
        {
            object result;
            var    expanded = TryMacroExpand(expr, env, out result);

            return(MakeList(Force(result), expanded));
        }
예제 #3
0
 public ScopeEntry(AnalysisScope scope, Symbol key, object value, ScopeFlags flags)
 {
     Scope = scope;
     Key   = key;
     Value = value;
     Flags = flags;
 }
예제 #4
0
 public FrameAndScope()
 {
     Frame              = new Frame();
     Scope              = new AnalysisScope();
     Scope.IsFileScope  = true;
     Scope.IsBlockScope = true;
 }
예제 #5
0
 public ScopeEntry(AnalysisScope scope, Symbol key, object value, ScopeFlags flags)
 {
     Scope         = scope;
     Key           = key;
     Value         = value;
     Flags         = flags;
     HoistIndex    = -1;
     HoistOriginal = null;
 }
예제 #6
0
        public static Expression Compile(object expr)
        {
            //
            // Empty lexical scope!
            //
            var scope = new AnalysisScope();

            return(Compile(expr, scope));
        }
예제 #7
0
        public static object Eval(object expr)
        {
            //
            // Empty lexical scope!
            //
            var scope = new AnalysisScope();

            return(Execute(Compile(expr, scope)));
        }
예제 #8
0
        public static object MacroExpand(object expr, AnalysisScope env)
        {
            var form = expr;

            while (TryMacroExpand(form, env, out form))
            {
            }

            return(form);
        }
예제 #9
0
        public static AnalysisScope ReconstructAnalysisScope(Frame context, AnalysisScope consoleScope = null)
        {
            if (consoleScope == null)
            {
                consoleScope = new AnalysisScope();
            }

            var stack = new Stack <AnalysisScope>();

            stack.Push(consoleScope);

            var scope = consoleScope;

            scope.Names = null;

            for (var frame = context; frame != null; frame = frame.Link)
            {
                if (frame.Names == null)
                {
                    continue;
                }

                if (scope == null)
                {
                    scope = new AnalysisScope();
                    stack.Push(scope);
                }

                scope.Names = new List <Symbol>();

                foreach (var key in frame.Names)
                {
                    scope.DefineFrameLocal(key, ScopeFlags.All);
                }

                scope = null;
            }

            scope = null;

            while (stack.Count > 0)
            {
                var top = stack.Pop();
                top.Parent = scope;
                scope      = top;
            }

            return(scope);
        }
예제 #10
0
        public static AnalysisScope ReconstructAnalysisScope(Frame context, AnalysisScope consoleScope = null)
        {
            if (consoleScope == null)
            {
                consoleScope = new AnalysisScope();
            }

            /*
             * var stack = new Stack<AnalysisScope>();
             * stack.Push(consoleScope);
             *
             * var scope = consoleScope;
             * scope.Names = null;
             *
             * for (var frame = context; frame != null; frame = frame.Link)
             * {
             *  if (frame.Names == null)
             *  {
             *      continue;
             *  }
             *
             *  if (scope == null)
             *  {
             *      scope = new AnalysisScope();
             *      stack.Push(scope);
             *  }
             *
             *  scope.Names = new List<Symbol>();
             *
             *  foreach (var key in frame.Names)
             *  {
             *      scope.DefineFrameLocal(key, ScopeFlags.All);
             *  }
             *
             *  scope = null;
             * }
             *
             * scope = null;
             *
             * while (stack.Count > 0)
             * {
             *  var top = stack.Pop();
             *  top.Parent = scope;
             *  scope = top;
             * }
             */

            return(consoleScope);
        }
예제 #11
0
        public static object MacroExpandBase(object expr, AnalysisScope env)
        {
            var sym = expr as Symbol;

            if (sym != null)
            {
                if (!Keywordp(sym))
                {
                    var entry = env.FindLocal(sym, ScopeFlags.Referenced);
                    var macro = (entry != null) ? entry.SymbolMacroValue : sym.SymbolMacroValue;
                    if (macro != null)
                    {
                        return(macro.Form);
                    }
                }
                return(expr);
            }

            var form = expr as Cons;

            if (form != null)
            {
                var head = First(form) as Symbol;

                if (head == null || Keywordp(head))
                {
                    return(expr);
                }

                var entry = env.FindLocal(head, ScopeFlags.Referenced);
                var macro = (entry != null) ? entry.MacroValue : head.MacroValue;
                if (macro != null)
                {
                    var hook = (IApply)GetDynamic(Symbols.MacroexpandHook);
                    return(Funcall(hook, macro, form, new AnalysisScope(env)));
                }
                else
                {
                    return(expr);
                }
            }

            return(expr);
        }
예제 #12
0
        public static Cons CodeWalkListAt(int pos, Cons forms, Func <object, AnalysisScope, object> transform, AnalysisScope env)
        {
            if (env == null)
            {
                env = new AnalysisScope(null);
            }

            if (forms == null)
            {
                return(null);
            }
            else if (pos > 0)
            {
                return(MakeCons(forms.Car, CodeWalkListAt(pos - 1, forms.Cdr, transform, env)));
            }
            else
            {
                return(MakeCons(CodeWalk(forms.Car, transform, env), CodeWalkListAt(0, forms.Cdr, transform, env)));
            }
        }
예제 #13
0
        public void CheckVariables()
        {
            string context = null;

            for (AnalysisScope sc = this; sc != null; sc = sc.Parent)
            {
                if (sc.IsLambda && sc.Name != null)
                {
                    context = sc.Name.ContextualName;
                    break;
                }
            }

            if (context == null)
            {
                // If there is no lambda, this code is probably running in the repl
                // and warnings are not very usefull.
                return;
            }

            foreach (var v in Variables)
            {
                if (v.Ignorable)
                {
                }
                else if (!v.Referenced)
                {
                    if (!v.Key.SuppressWarnings && !v.Ignore)
                    {
                        PrintWarning(context, "unreferenced variable", v.Key);
                    }
                }
                else if (!v.Initialized && !v.Assigned)
                {
                    PrintWarning(context, "uninitialized variable", v.Key);
                }
            }
        }
예제 #14
0
 public static object MacroExpandAll(object form, AnalysisScope env)
 {
     return(CodeWalk(form, MacroExpand, env));
 }
예제 #15
0
        public static Expression CompileGetMember(Cons form, AnalysisScope scope)
        {
            // (attr target property)
            CheckLength(form, 3);
            var member = Third(form);

            if (member is string || Keywordp(member))
            {
                var name = GetDesignatedString(member);
                var target = Compile(Second(form), scope);
                var binder = GetGetMemberBinder(name);
                return Expression.Dynamic(binder, typeof(object), new Expression[] { target });
            }
            else if (member is Cons && First(member) == Symbols.Quote && Second(member) is Symbol)
            {
                var name = ((Symbol)Second(member)).Name;
                var target = Compile(Second(form), scope);
                var binder = GetGetMemberBinder(name);
                return Expression.Dynamic(binder, typeof(object), new Expression[] { target });
            }
            else {
                // not a constant name
                var newform = MakeCons(Symbols.Funcall, form);
                return CompileFunctionCall(newform, scope);
            }
        }
예제 #16
0
        public static Expression CompileGetVariable(Symbol sym, AnalysisScope scope, bool useEnvironment)
        {
            if (sym.IsDynamic)
            {
                return CallRuntime(GetDynamicMethod, Expression.Constant(sym));
            }
            else if (Keywordp(sym))
            {
                return Expression.Constant(sym, typeof(Symbol));
            }
            else {
                int depth;
                ScopeEntry entry;

                if (scope.FindLocal(sym, ScopeFlags.Referenced, out depth, out entry))
                {
                    Expression code;

                    if (entry.MacroValue != null || entry.SymbolMacroValue != null)
                    {
                        throw new LispException("{0}: cannot compile reference to (symbol)macro variable", sym);
                    }
                    else if (entry.Parameter != null)
                    {
                        code = entry.Parameter;
                    }
                    else {
                        code = CallRuntime(GetLexicalMethod, Expression.Constant(depth), Expression.Constant(entry.Index));
                    }

                    if ((entry.Flags & ScopeFlags.Future) != 0)
                    {
                        // This also handles the lazy-future case.
                        code = CallRuntime(GetTaskResultMethod, Expression.Convert(code, typeof(ThreadContext)));
                    }
                    else if ((entry.Flags & ScopeFlags.Lazy) != 0)
                    {
                        code = CallRuntime(GetDelayedExpressionResultMethod, Expression.Convert(code, typeof(DelayedExpression)));
                    }

                    return code;
                }
                else if (useEnvironment)
                {
                    return Expression.PropertyOrField(Expression.Constant(sym), "CheckedOrEnvironmentValue");
                }
                else {
                    return Expression.PropertyOrField(Expression.Constant(sym), "CheckedValue");
                }
            }
        }
예제 #17
0
 public AnalysisScope(AnalysisScope parent = null)
 {
     Parent       = parent;
     LambdaParent = parent == null ? null : parent.LambdaParent;
     Name         = parent == null ? Symbols.Anonymous : parent.Name;
 }
예제 #18
0
        public static Cons CodeWalkListAt(int pos, Cons forms, Func<object, AnalysisScope, object> transform, AnalysisScope env)
        {
            if (env == null)
            {
                env = new AnalysisScope(null, "codewalk");
            }

            if (forms == null)
            {
                return null;
            }
            else if (pos > 0)
            {
                return MakeCons(forms.Car, CodeWalkListAt(pos - 1, forms.Cdr, transform, env));
            }
            else {
                return MakeCons(CodeWalk(forms.Car, transform, env), CodeWalkListAt(0, forms.Cdr, transform, env));
            }
        }
예제 #19
0
 public static AnalysisScope MakeEnvironment(AnalysisScope env)
 {
     return new AnalysisScope(env, "env");
 }
예제 #20
0
        public static Expression CompileLambda(Cons form, AnalysisScope scope)
        {
            // lambda [name] args body

            string doc;
            if (Symbolp(Second(form)))
            {
                CheckMinLength(form, 3);
                return CompileLambdaDef((Symbol)Second(form), Cddr(form), scope, LambdaKind.Function, out doc);
            }
            else {
                CheckMinLength(form, 2);
                return CompileLambdaDef(null, Cdr(form), scope, LambdaKind.Function, out doc);
            }
        }
예제 #21
0
 public static Cons CodeWalkList(Cons forms, Func<object, AnalysisScope, object> transform, AnalysisScope env)
 {
     return CodeWalkListAt(0, forms, transform, env);
 }
예제 #22
0
 public static bool FindNameOrMacroInEnvironment(Symbol sym, AnalysisScope env)
 {
     return(env != null && env.FindLocal(sym) != null);
 }
예제 #23
0
        public static Expression CompileLambdaDef(Symbol name, Cons forms, AnalysisScope scope, LambdaKind kind, out string doc)
        {
            CheckMinLength(forms, 0);

            if (Length(forms) == 1)
            {
                PrintWarning("Function body contains no forms.");
            }

            var args = (Cons)First(forms);
            var body = Cdr(forms);
            var funscope = new AnalysisScope(scope, name == null ? null : name.Name);
            funscope.IsLambda = true;
            var template = new LambdaDefinition();
            template.Name = name;
            template.Signature = CompileFormalArgs(args, scope, kind);

            if (kind == LambdaKind.Method)
            {
                var container = name.Value as MultiMethod;
                if (container != null)
                {
                    var m = template.Signature;
                    var g = container.Signature;
                    var m1 = m.RequiredArgsCount;
                    var m2 = m.Parameters.Count;
                    var m3 = m.ArgModifier;
                    var g1 = g.RequiredArgsCount;
                    var g2 = g.Parameters.Count;
                    var g3 = g.ArgModifier;

                    if (m1 != g1)
                    {
                        throw new LispException("Method does not match multi-method: number of required arguments");
                    }
                    if (m3 != g3)
                    {
                        throw new LispException("Method does not match multi-method: different argument modifiers");
                    }
                    if (g3 != Symbols.Key && m2 != g2)
                    {
                        throw new LispException("Method does not match multi-method: number of arguments");
                    }
                    if (g3 == Symbols.Key)
                    {
                        // Replace keyword parameters with the full list from the generic definition, but keep the defaults
                        var usedKeys = template.Signature.Parameters.GetRange(m1, m2 - m1);
                        var replacementKeys = container.Signature.Parameters.GetRange(g1, g2 - g1);
                        template.Signature.Parameters.RemoveRange(m1, m2 - m1);
                        template.Signature.Names.RemoveRange(m1, m2 - m1);
                        foreach (var par in replacementKeys)
                        {
                            var oldpar = usedKeys.FirstOrDefault(x => x.Sym == par.Sym);
                            if (oldpar != null)
                            {
                                var newpar = new ParameterDef(par.Sym, initForm: oldpar.InitForm);
                                template.Signature.Parameters.Add(newpar);
                                template.Signature.Names.Add(par.Sym);
                            }
                            else {
                                // Insert place holder
                                var newpar = new ParameterDef(par.Sym, hidden: true);
                                template.Signature.Parameters.Add(newpar);
                                template.Signature.Names.Add(newpar.Sym);
                            }
                        }
                    }
                }
            }
            if (name != null)
            {
                template.Syntax = MakeListStar(template.Name, args);
            }

            template.Source = MakeListStar(Symbols.Lambda, args, body);

            doc = "";

            if (body != null)
            {
                if (body.Car is string)
                {
                    doc = (string)body.Car;
                    if (body.Cdr != null)
                    {
                        body = body.Cdr;
                    }
                }
            }

            var lambdaListNative = funscope.DefineNativeLocal(Symbols.LambdaList, ScopeFlags.All);
            var selfNative = funscope.DefineNativeLocal(Symbols.Self, ScopeFlags.All);
            var argsNative = funscope.DefineNativeLocal(Symbols.Args, ScopeFlags.All);
            Expression code;

            var rawparams = template.Signature.ArgModifier == Symbols.RawParams;
            var names = GetLambdaArgumentNames(template.Signature);
            var temp = GenTemp();
            var body4 = FormatCode(LambdaTemplate, Symbols.Args, temp, GetDeclarations(rawparams, names, temp), body);
            code = Compile(body4, funscope);

            template.Proc = CompileToFunction3(code, lambdaListNative, selfNative, argsNative);

            return CallRuntime(MakeLambdaClosureMethod, Expression.Constant(template, typeof(LambdaDefinition)));
        }
예제 #24
0
 public static void AddMacroToEnvironment(Symbol localName, Symbol globalName, AnalysisScope env)
 {
     env.DefineMacro(localName, globalName.CompilerValue, ScopeFlags.All);
 }
예제 #25
0
 public static Expression CompileLazyVar(Cons form, AnalysisScope scope)
 {
     return CompileVarInScope(form, scope, lazy: true, constant: true);
 }
예제 #26
0
 public static void AddMacroToEnvironment(Symbol localName, Symbol globalName, AnalysisScope env)
 {
     env.DefineMacro(localName, globalName.CompilerValue, ScopeFlags.All);
 }
예제 #27
0
 public static Expression CompileFutureVar(Cons form, AnalysisScope scope)
 {
     return CompileVarInScope(form, scope, future: true);
 }
예제 #28
0
        public static Cons CodeWalkListTry(Cons forms, Func<object, AnalysisScope, object> transform, AnalysisScope env)
        {
            if (forms == null)
            {
                return null;
            }
            else {
                object result;
                if (forms.Car is Cons)
                {
                    var list = (Cons)forms.Car;
                    var head = First(list);
                    if (head == Symbols.Catch)
                    {
                        // catch (sym type) expr...
                        result = CodeWalkListAt(2, list, transform, env);
                    }
                    else if (head == Symbols.Finally)
                    {
                        // finally expr...
                        result = CodeWalkListAt(1, list, transform, env);
                    }
                    else {
                        result = CodeWalk(list, transform, env);
                    }
                }
                else {
                    result = CodeWalk(forms.Car, transform, env);
                }

                return MakeCons(result, CodeWalkListTry(forms.Cdr, transform, env));
            }
        }
예제 #29
0
 public static bool TryMacroExpand(object expr, AnalysisScope env, out object result)
 {
     result = MacroExpandBase(expr, env);
     return result != expr;
 }
예제 #30
0
 public static AnalysisScope MakeEnvironment(AnalysisScope env)
 {
     return(new AnalysisScope(env));
 }
예제 #31
0
        public static Expression CompileGoto(Cons form, AnalysisScope scope)
        {
            // goto symbol [value]
            CheckMinLength(form, 2);
            CheckMaxLength(form, 3);
            var tag = CheckSymbol(Second(form));
            AnalysisScope labelScope;
            LabelTarget label;
            if (!TryFindLabel(scope, tag.LongName, out labelScope, out label))
            {
                throw new LispException("Label {0} not found", tag);
            }

            var value = Compile(Third(form), scope);

            if (labelScope == scope)
            {
                var code = Expression.Block(
                               typeof(object),
                               Expression.Assign(labelScope.Tilde, value),
                               Expression.Goto(label),
                               CompileLiteral(null));

                return code;
            }
            else {
                if (labelScope.TagBodySaved == null)
                {
                    labelScope.TagBodySaved = Expression.Parameter(typeof(ThreadContextState), "saved-for-goto");
                }

                var code = Expression.Block(
                               typeof(object),
                               Expression.Assign(labelScope.Tilde, value),
                               CallRuntime(RestoreStackAndFrameMethod, labelScope.TagBodySaved),
                               Expression.Goto(label),
                               CompileLiteral(null));

                return code;
            }
        }
예제 #32
0
 public ScopeEntry(AnalysisScope scope, Symbol key, object value, ScopeFlags flags)
 {
     Scope = scope;
     Key = key;
     Value = value;
     Flags = flags;
 }
예제 #33
0
 public static Cons CodeWalkList(Cons forms, Func <object, AnalysisScope, object> transform, AnalysisScope env)
 {
     return(CodeWalkListAt(0, forms, transform, env));
 }
예제 #34
0
        public static AnalysisScope ReconstructAnalysisScope(Frame context, AnalysisScope consoleScope = null)
        {
            if (consoleScope == null)
            {
                consoleScope = new AnalysisScope();
            }

            var stack = new Stack<AnalysisScope>();
            stack.Push(consoleScope);

            var scope = consoleScope;
            scope.Names = null;

            for (var frame = context; frame != null; frame = frame.Link)
            {
                if (frame.Names == null)
                {
                    continue;
                }

                if (scope == null)
                {
                    scope = new AnalysisScope();
                    stack.Push(scope);
                }

                scope.Names = new List<Symbol>();

                foreach (var key in frame.Names)
                {
                    scope.DefineFrameLocal(key, ScopeFlags.All);
                }

                scope = null;
            }

            scope = null;

            while (stack.Count > 0)
            {
                var top = stack.Pop();
                top.Parent = scope;
                scope = top;
            }

            return scope;
        }
예제 #35
0
        public static Cons CodeWalkListTry(Cons forms, Func <object, AnalysisScope, object> transform, AnalysisScope env)
        {
            if (forms == null)
            {
                return(null);
            }
            else
            {
                object result;
                if (forms.Car is Cons)
                {
                    var list = (Cons)forms.Car;
                    var head = First(list);
                    if (head == Symbols.Catch)
                    {
                        // catch (sym type) expr...
                        result = CodeWalkListAt(2, list, transform, env);
                    }
                    else if (head == Symbols.Finally)
                    {
                        // finally expr...
                        result = CodeWalkListAt(1, list, transform, env);
                    }
                    else
                    {
                        result = CodeWalk(list, transform, env);
                    }
                }
                else
                {
                    result = CodeWalk(forms.Car, transform, env);
                }

                return(MakeCons(result, CodeWalkListTry(forms.Cdr, transform, env)));
            }
        }
예제 #36
0
 public static Expression CompileLabel(Cons form, AnalysisScope scope)
 {
     throw new LispException("Labels must be placed at the top level of a implicit or explicit DO block");
 }
예제 #37
0
        public static object CodeWalk(object form, Func <object, AnalysisScope, object> transform, AnalysisScope env)
        {
            if (env == null)
            {
                env = new AnalysisScope(null);
            }

            form = transform(form, env);

            if (!Consp(form))
            {
                return(form);
            }

            var forms = (Cons)form;
            var head  = First(forms) as Symbol;

            if (head != null && head.SpecialFormValue != null)
            {
                var tag = head.Name;
                switch (tag)
                {
                case "declare":
                case "goto":
                case "quote":
                {
                    break;
                }

                case "def":
                case "var":
                case "let":
                case "defconstant":
                case "lazy":
                case "future":
                case "setq":
                {
                    forms = CodeWalkListAt(2, forms, transform, env);
                    var variables = Second(forms);
                    if (variables is Cons)
                    {
                        foreach (var sym in ToIter(variables))
                        {
                            env.DefineVariable((Symbol)sym, ScopeFlags.All);
                        }
                    }
                    else
                    {
                        env.DefineVariable((Symbol)variables, ScopeFlags.All);
                    }
                    break;
                }

                case "lambda":
                case "lambda*":
                {
                    return(form);
                    //throw new LispException( "lambda not supported by code walker" );
                }

                case "letmacro":
                case "let-symbol-macro":
                {
                    return(form);
                }

                case "letfun":
                {
                    return(form);
                    //throw new LispException( "letfun not supported by code walker" );
                }

                case "try":
                {
                    forms = MakeCons(Symbols.Try, CodeWalkListTry(Cdr(forms), transform, env));
                    break;
                }

                case "defmacro":
                case "defun":
                case "defun*":
                case "defmulti":
                case "defmethod":
                {
                    return(form);
                    //throw new LispException( "defun, defmacro, defmulti and defmethod not supported by code walker" );
                }

                case "do":
                {
                    var env2 = new AnalysisScope(env);
                    forms = CodeWalkListAt(1, forms, transform, env2);
                    break;
                }

                default:
                {
                    forms = CodeWalkListAt(1, forms, transform, env);
                    break;
                }
                }
            }
            else
            {
                forms = CodeWalkListAt(0, forms, transform, env);
            }

            return(forms);
        }
예제 #38
0
 public static Expression CompileIf(Cons form, AnalysisScope scope)
 {
     // if expr expr [expr]
     CheckMinLength(form, 3);
     CheckMaxLength(form, 4);
     var testExpr = Compile(Second(form), scope);
     var thenExpr = Expression.Convert(Compile(Third(form), scope), typeof(object));
     var elseExpr = Expression.Convert(Compile(Fourth(form), scope), typeof(object));
     var test = WrapBooleanTest(testExpr);
     return Expression.Condition(test, thenExpr, elseExpr);
 }
예제 #39
0
 public static Expression CompileGetElt(Cons form, AnalysisScope scope)
 {
     // (elt target indexes)
     CheckMinLength(form, 3);
     var args = new List<Expression>(ConvertToEnumerableObject(form.Cdr).Select(x => Compile(x, scope)));
     var binder = GetGetIndexBinder(args.Count - 1);
     return CompileDynamicExpression(binder, typeof(object), args);
 }
예제 #40
0
 public static Expression CompileHiddenVar(Cons form, AnalysisScope scope)
 {
     return CompileVarInScope(form, scope, native: true);
 }
예제 #41
0
 public static object Eval(object expr)
 {
     //
     // Empty lexical scope!
     //
     var scope = new AnalysisScope();
     return Execute(Compile(expr, scope));
 }
예제 #42
0
 public static Expression Compile(object expr, AnalysisScope scope)
 {
     if (DebugMode)
     {
         var context = CurrentThreadContext;
         var saved = context.SaveStackAndFrame(null, MakeList(Symbols.Compiling, expr));
         var result = CompileWrapped(expr, scope);
         context.RestoreStackAndFrame(saved);
         return result;
     }
     else {
         var result = CompileWrapped(expr, scope);
         return result;
     }
 }
예제 #43
0
 public static bool TryMacroExpand(object expr, AnalysisScope env, out object result)
 {
     result = MacroExpandBase(expr, env);
     return(result != expr);
 }
예제 #44
0
 public static bool FindNameOrMacroInEnvironment(Symbol sym, AnalysisScope env)
 {
     return env != null && env.FindLocal(sym) != null;
 }
예제 #45
0
 public AnalysisScope(AnalysisScope parent, string name)
     : this()
 {
     Parent = parent;
     Name = name;
 }
예제 #46
0
        public static object MacroExpand(object expr, AnalysisScope env)
        {
            var form = expr;

            while (TryMacroExpand(form, env, out form))
            {
            }

            return form;
        }
예제 #47
0
 public FrameAndScope()
 {
     Frame = new Frame();
     Scope = new AnalysisScope();
     Scope.IsFileScope = true;
     Scope.IsBlockScope = true;
 }
예제 #48
0
 public static Cons MacroExpand1(object expr, AnalysisScope env)
 {
     object result;
     var expanded = TryMacroExpand(expr, env, out result);
     return MakeList(Force(result), expanded);
 }
예제 #49
0
        public static object CodeWalk(object form, Func<object, AnalysisScope, object> transform, AnalysisScope env)
        {
            if (env == null)
            {
                env = new AnalysisScope(null, "codewalk");
            }

            form = transform(form, env);

            if (!Consp(form))
            {
                return form;
            }

            var forms = (Cons)form;
            var head = First(forms) as Symbol;

            if (head != null && head.SpecialFormValue != null)
            {
                var tag = head.Name;
                switch (tag)
                {
                    case "declare":
                    case "goto":
                    case "quote":
                        {
                            break;
                        }
                    case "def":
                    case "var":
                    case "hidden-var":
                    case "let":
                    case "defconstant":
                    case "lazy":
                    case "future":
                    case "setq":
                        {
                            forms = CodeWalkListAt(2, forms, transform, env);
                            var variables = Second(forms);
                            if (variables is Cons)
                            {
                                foreach (var sym in ToIter(variables))
                                {
                                    env.DefineFrameLocal((Symbol)sym, ScopeFlags.All);
                                }
                            }
                            else {
                                env.DefineFrameLocal((Symbol)variables, ScopeFlags.All);
                            }
                            break;
                        }
                    case "lambda":
                    case "lambda*":
                        {
                            return form;
                            //throw new LispException( "lambda not supported by code walker" );
                        }
                    case "letmacro":
                    case "let-symbol-macro":
                        {
                            return form;
                        }
                    case "letfun":
                        {
                            return form;
                            //throw new LispException( "letfun not supported by code walker" );
                        }
                    case "try":
                        {
                            forms = MakeCons(Symbols.Try, CodeWalkListTry(Cdr(forms), transform, env));
                            break;
                        }
                    case "defmacro":
                    case "defun":
                    case "defun*":
                    case "defmulti":
                    case "defmethod":
                        {
                            return form;
                            //throw new LispException( "defun, defmacro, defmulti and defmethod not supported by code walker" );
                        }
                    case "do":
                        {
                            var env2 = new AnalysisScope(env, "do");
                            forms = CodeWalkListAt(1, forms, transform, env2);
                            break;
                        }
                    default:
                        {
                            forms = CodeWalkListAt(1, forms, transform, env);
                            break;
                        }
                }
            }
            else {
                forms = CodeWalkListAt(0, forms, transform, env);
            }

            return forms;
        }
예제 #50
0
 public static object MacroExpandAll(object form, AnalysisScope env)
 {
     return CodeWalk(form, MacroExpand, env);
 }
예제 #51
0
        public bool FindLocal(Symbol sym, ScopeFlags reason, out int depth, out ScopeEntry entry)
        {
            bool noCapturedNativeParametersBeyondThisPoint = false;

            depth = 0;
            entry = null;

            for (AnalysisScope sc = this; sc != null; sc = sc.Parent)
            {
                ScopeEntry item;

                if (sc.IsBlockScope && sym == Symbols.Tilde)
                {
                    if (sc.Tilde == null)
                    {
                        sc.Tilde = sc.DefineNativeLocal(Symbols.Tilde, ScopeFlags.All);
                    }
                }

                for (var i = sc.Variables.Count - 1; i >= 0; --i)
                {
                    item = sc.Variables[i];

                    // Looking for exact match
                    if (LexicalSymEqual(item.Key, sym))
                    {
                        entry       = item;
                        item.Flags |= reason;

                        if (item.Index != -1 || item.MacroValue != null || item.SymbolMacroValue != null)
                        {
                        }
                        else if (reason != 0 && noCapturedNativeParametersBeyondThisPoint && !LexicalSymEqual(sym, Symbols.Tilde))
                        {
                            // Linq.Expression closures do not support native variables defined
                            // outside the LambdaExpression. Whenever we encounter such a variable
                            // it is added to the free variables and also added as frame variable
                            // to keep the compiler happy.
                            // The recompile that comes later uses the list of free variables to
                            // choose the correct implementation scheme.
                            sc.FreeVariables.Add(sym);
                            sc.ChangeNativeToFrameLocal(item);
                        }

                        return(true);
                    }
                }

                if (sc.IsBlockScope && sym == Symbols.Tilde)
                {
                    // boundary for ~ variable which is tightly coupled to its DO block.
                    break;
                }

                if (sc.IsLambda)
                {
                    // boundary for native variables in closures.
                    noCapturedNativeParametersBeyondThisPoint = true;
                }

                if (sc.Names != null)
                {
                    ++depth;
                }
            }

            depth = 0;

            return(false);
        }
예제 #52
0
        public static object MacroExpandBase(object expr, AnalysisScope env)
        {
            var sym = expr as Symbol;

            if (sym != null)
            {
                var entry = env.FindLocal(sym);
                var macro = (entry != null) ? entry.SymbolMacroValue : sym.SymbolMacroValue;
                if (macro != null)
                {
                    return macro.Form;
                }
                else {
                    return expr;
                }
            }

            var form = expr as Cons;

            if (form != null)
            {
                var head = First(form) as Symbol;

                if (head == null)
                {
                    return expr;
                }

                var entry = env.FindLocal(head);
                var macro = (entry != null) ? entry.MacroValue : head.MacroValue;
                if (macro != null)
                {
                    var hook = (IApply)GetDynamic(Symbols.MacroexpandHook);
                    return Funcall(hook, macro, form, new AnalysisScope(env, "try-macroexpand"));
                }
                else {
                    return expr;
                }
            }

            return expr;
        }
예제 #53
0
 public AnalysisScope(AnalysisScope parent, string name)
     : this()
 {
     Parent = parent;
     Name   = name;
 }
예제 #54
0
        public static Expression CompileFunctionCall(Cons form, AnalysisScope scope)
        {
            if (OptimizerEnabled)
            {
                var expr = Optimizer(form);
                if (expr != form)
                {
                    return Expression.Constant(expr, typeof(object));
                }
            }

            CheckMinLength(form, 1);
            var formFunc = First(form);
            var formArgs = Cdr(form);
            var member = formFunc as Cons;

            if (member != null && First(member) == Symbols.Dot)
            {
                var names = (string)Second(member);
                var args = ToIter(formArgs).Cast<object>().Select(x => Compile(x, scope)).ToArray();
                return AccessorLambdaMetaObject.MakeExpression(false, names, args);
            }
            else if (member != null && First(member) == Symbols.NullableDot)
            {
                var names = (string)Second(member);
                var args = ToIter(formArgs).Cast<object>().Select(x => Compile(x, scope)).ToArray();
                return AccessorLambdaMetaObject.MakeExpression(true, names, args);
            }
            else {
                var func = Compile(formFunc, scope);
                var args = new List<Expression>();
                args.Add(func);
                foreach (object a in ToIter(formArgs))
                {
                    args.Add(Compile(a, scope));
                }
                var binder = GetInvokeBinder(Length(formArgs));
                var code = CompileDynamicExpression(binder, typeof(object), args);
                if (!DebugMode)
                {
                    return code;
                }
                else {
                    return WrapEvaluationStack(code, null, form);
                }
            }
        }