Example #1
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);
        }
Example #2
0
 public static bool FindNameOrMacroInEnvironment(Symbol sym, AnalysisScope env)
 {
     return env != null && env.FindLocal(sym) != null;
 }
Example #3
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;
        }
Example #4
0
 public static bool FindNameOrMacroInEnvironment(Symbol sym, AnalysisScope env)
 {
     return(env != null && env.FindLocal(sym) != null);
 }
Example #5
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");
                }
            }
        }
Example #6
0
 public static Expression CompileDeclare(Cons form, AnalysisScope scope)
 {
     CheckLength(form, 2);
     foreach (var item in Cdr(form))
     {
         if (item is Cons)
         {
             var declaration = (Cons)item;
             var declare = (Symbol)First(declaration);
             switch (declare.Name)
             {
                 case "ignore":
                     {
                         if (!scope.IsBlockScope)
                         {
                             throw new LispException("(declare (ignore ...)) statement requires block scope: {0}", form);
                         }
                         foreach (Symbol sym in Cdr(declaration))
                         {
                             scope.FindLocal(sym, ScopeFlags.Ignore);
                         }
                         break;
                     }
                 case "ignorable":
                     {
                         if (!scope.IsBlockScope)
                         {
                             throw new LispException("(declare (ignorable ...)) statement requires block scope: {0}", form);
                         }
                         foreach (Symbol sym in Cdr(declaration))
                         {
                             scope.FindLocal(sym, ScopeFlags.Ignorable);
                         }
                         break;
                     }
                 case "dynamic":
                     {
                         foreach (Symbol sym in Cdr(declaration))
                         {
                             sym.IsDynamic = true;
                         }
                         break;
                     }
                 default:
                     {
                         break;
                     }
             }
         }
     }
     return Expression.Constant(null, typeof(object));
 }
Example #7
0
        public static Expression CompileWrapped(object expr1, AnalysisScope scope)
        {
            var expr = MacroExpand(expr1, scope);

            // At this point expr is either not a macro call, or it is a macro call
            // that refused to expand by returning the &whole parameter.

            if (expr is Symbol)
            {
                var sym = (Symbol)expr;
                // This optimization does not help much, I think.
                //if ( sym.IsDynamic || scope.HasLocalVariable( sym, int.MaxValue ) )
                //{
                //    return CompileGetVariable( sym, scope );
                //}
                //else if ( sym.IsFunction && ( sym.Value is ImportedFunction || sym.Value is ImportedConstructor ) )
                //{
                //    return Expression.Constant( sym.Value, typeof( object ) );
                //}
                //else
                {
                    return CompileGetVariable(sym, scope, false);
                }
            }
            else if (expr is Cons)
            {
                var form = (Cons)expr;

                if (First(form) is Symbol)
                {
                    var head = (Symbol)First(form);
                    var shadowed = scope.FindLocal(head) != null;

                    if (shadowed)
                    {
                        return CompileFunctionCall(form, scope);
                    }
                    else if (head.SpecialFormValue != null)
                    {
                        return head.SpecialFormValue.Helper(form, scope);
                    }
                    else {
                        return CompileFunctionCall(form, scope);
                    }
                }
                else {
                    return CompileFunctionCall(form, scope);
                }
            }
            else {
                // anything else is a literal
                return CompileLiteral(expr);
            }
        }
Example #8
0
        public static Expression CompileSetq(Cons form, AnalysisScope scope)
        {
            // setq sym expr
            CheckLength(form, 3);

            var sym = CheckSymbol(Second(form));
            var form2 = MacroExpand(sym, scope);
            if (form2 != sym)
            {
                // symbol macro - change setq to setf
                var expr = MakeListStar(Symbols.Setf, form2, Cddr(form));
                return Compile(expr, scope);
            }

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

            if (sym.IsDynamic)
            {
                if (scope.Parent == null && !scope.IsFileScope)
                {
                    // REPL does not require def before set.
                    return Expression.Assign(Expression.PropertyOrField(Expression.Constant(sym), "LessCheckedValue"), value);
                }
                else {
                    return CallRuntime(SetDynamicMethod, Expression.Constant(sym), value);
                }
            }
            else {
                int depth;
                ScopeEntry entry;

                if (scope.FindLocal(sym, ScopeFlags.Assigned, out depth, out entry))
                {
                    if (entry.MacroValue != null || entry.SymbolMacroValue != null)
                    {
                        throw new LispException("{0}: cannot compile reference to (symbol)macro variable", sym);
                    }

                    var constant = (entry.Flags & ScopeFlags.Constant) != 0;

                    if (constant)
                    {
                        throw new LispException("Cannot assign to a constant, future or lazy variable: {0}", sym);
                    }

                    if (entry.Parameter != null)
                    {
                        return Expression.Assign(entry.Parameter, value);
                    }
                    else {
                        return CallRuntime(SetLexicalMethod, Expression.Constant(depth), Expression.Constant(entry.Index), value);
                    }
                }
                else if (scope.Parent == null)
                {
                    // REPL assigments
                    return Expression.Assign(Expression.PropertyOrField(Expression.Constant(sym), "LessCheckedValue"), value);
                }
                else {
                    return Expression.Assign(Expression.PropertyOrField(Expression.Constant(sym), "CheckedValue"), value);
                }
            }
        }