コード例 #1
0
ファイル: compiler.cs プロジェクト: jantolenaar/kiezellisp
 public static Expression CompileLetSymbolMacro(Cons form, AnalysisScope scope)
 {
     // let-symbol-macro name form
     CheckLength(form, 3);
     CheckMinLength(form, 3);
     var sym = CheckSymbol(Second(form));
     if (sym.IsDynamic)
     {
         throw new LispException("Invalid symbol-macro name: {0}", sym);
     }
     if (!scope.IsBlockScope)
     {
         throw new LispException("Statement requires block or file scope: {0}", form);
     }
     if (sym == Symbols.Tilde)
     {
         throw new LispException("\"~\" is a reserved symbol name");
     }
     if (scope.FindDuplicate(sym))
     {
         throw new LispException("Duplicate declaration of variable: {0}", sym);
     }
     var macro = new SymbolMacro(Third(form));
     scope.DefineMacro(sym, macro, ScopeFlags.SymbolMacro | ScopeFlags.All);
     return Expression.Constant(null);
 }
コード例 #2
0
ファイル: compiler.cs プロジェクト: jantolenaar/kiezellisp
        public static Expression CompileLexicalVarInScope(Cons form, AnalysisScope scope, bool native, bool future, bool lazy, bool constant)
        {
            // var sym [expr]
            var sym = (Symbol)Second(form);
            var initForm = Third(form);

            if (!scope.IsBlockScope)
            {
                throw new LispException("Statement requires block or file scope: {0}", form);
            }
            if (sym == Symbols.Tilde)
            {
                throw new LispException("\"~\" is a reserved symbol name");
            }
            if (scope.FindDuplicate(sym))
            {
                throw new LispException("Duplicate declaration of variable: {0}", sym);
            }

            constant |= future | lazy;

            // Initializer must be compiled before adding the variable
            // since it may already exist. Works like nested LET forms.
            var flags = (ScopeFlags)0;
            Expression val;

            if (Length(form) == 2)
            {
                if (constant)
                {
                    throw new LispException("Constant, future or lazy variable must have an initializer: {0}", form);
                }

                val = CompileLiteral(null);
            }
            else {
                flags |= ScopeFlags.Initialized | (constant ? ScopeFlags.Constant : 0);
                if (lazy && future)
                {
                    // Wrap initializer in TASK macro and wrap references to the variable in a
                    // GetTaskResult call (see CompileGetVariable).
                    flags |= ScopeFlags.Lazy | ScopeFlags.Future;
                    val = Compile(MakeList(Symbols.CreateTask, MakeList(Symbols.Lambda, null, initForm), false), scope);
                }
                else if (lazy)
                {
                    // Wrap initializer in DELAY macro and wrap references to the variable in a
                    // FORCE call.
                    flags |= ScopeFlags.Lazy;
                    val = Compile(MakeList(MakeSymbol("system:create-delayed-expression"), MakeList(Symbols.Lambda, null, initForm)), scope);
                }
                else if (future)
                {
                    // Wrap initializer in TASK macro and wrap references to the variable in a
                    // GetTaskResult call (see CompileGetVariable).
                    flags |= ScopeFlags.Future;
                    val = Compile(MakeList(Symbols.CreateTask, MakeList(Symbols.Lambda, null, initForm), true), scope);
                }
                else {
                    val = Compile(initForm, scope);
                }
            }

            if (scope.IsFileScope)
            {
                int index = scope.DefineFrameLocal(sym, flags);
                return CallRuntime(SetLexicalMethod, Expression.Constant(0), Expression.Constant(index), val);
            }
            else if (native)
            {
                var parameter = scope.DefineNativeLocal(sym, flags);
                return Expression.Assign(parameter, val);
            }
            else if (!DebugMode && scope.FreeVariables != null && !scope.FreeVariables.Contains(sym))
            {
                var parameter = scope.DefineNativeLocal(sym, flags);
                return Expression.Assign(parameter, val);
            }
            else {
                int index = scope.DefineFrameLocal(sym, flags);
                return CallRuntime(SetLexicalMethod, Expression.Constant(0), Expression.Constant(index), val);
            }
        }
コード例 #3
0
ファイル: compiler.cs プロジェクト: jantolenaar/kiezellisp
 public static Expression CompileLetMacro(Cons form, AnalysisScope scope)
 {
     // letmacro name args body
     CheckMinLength(form, 3);
     var sym = CheckSymbol(Second(form));
     if (sym.IsDynamic)
     {
         throw new LispException("Invalid macro name: {0}", sym);
     }
     if (!scope.IsBlockScope)
     {
         throw new LispException("Statement requires block or file scope: {0}", form);
     }
     if (sym == Symbols.Tilde)
     {
         throw new LispException("\"~\" is a reserved symbol name");
     }
     if (scope.FindDuplicate(sym))
     {
         throw new LispException("Duplicate declaration of variable: {0}", sym);
     }
     string doc;
     var lambda = CompileLambdaDef(sym, Cddr(form), scope, LambdaKind.Macro, out doc);
     var closure = (LambdaClosure)Execute(lambda);
     scope.DefineMacro(sym, closure, ScopeFlags.Macro | ScopeFlags.All);
     return Expression.Constant(null);
 }