예제 #1
0
        public SequenceBodyExpression(Token token, string name, BlockExpression block, string debugName,
                                      IdentifierOperand state, IdentifierOperand enumerable)
            : base(token, name, new List <string>(), null, block, debugName)
        {
            _stateLabels = new List <LabelOperand>();

            State      = state;
            Enumerable = enumerable;
        }
예제 #2
0
        public FunctionContext(ExpressionCompiler compiler, string name)
        {
            _compiler = compiler;
            _instructions = new List<Instruction>();
            _loopLabels = new IndexedStack<Tuple<LabelOperand, LabelOperand>>();

            Name = name != null ? _compiler.Identifier(name) : null;
            Label = _compiler.MakeLabel("function");

            IdentifierCount = 0;
        }
예제 #3
0
        public bool Define(string name, bool isReadOnly)
        {
            if (IsDefined(name))
                return false;

            var frameScope = GetFrameScope();
            var id = frameScope._nextId++;
            var identifier = new IdentifierOperand(_localIndex, id, name, isReadOnly);
            _identifiers.Add(name, identifier);
            return true;
        }
예제 #4
0
        public FunctionContext(ExpressionCompiler compiler, int argIndex, int localIndex, Scope prevScope, string parentName, string name)
        {
            _instructions = new List<Instruction>();
            _loopLabels = new IndexedStack<Tuple<LabelOperand, LabelOperand>>();

            Compiler = compiler;
            ArgIndex = argIndex;
            LocalIndex = localIndex;

            Scope = prevScope;

            ParentName = parentName;
            Name = name;
            FullName = string.Format("{0}{1}{2}", parentName, string.IsNullOrEmpty(parentName) ? "" : ".", Name ?? "");

            AssignedName = name != null ? prevScope.Get(name) : null;
            Label = Compiler.MakeLabel("function");

            IdentifierCount = 0;
        }
예제 #5
0
        public override int Compile(FunctionContext context)
        {
            var isStatement    = Parent is IBlockExpression;
            var shouldBeGlobal = context.ArgIndex == 0 && context.Compiler.Options.MakeRootDeclarationsGlobal;
            var shouldStore    = Name != null;

            IdentifierOperand identifier = null;

            if (shouldStore && !shouldBeGlobal)
            {
                if (!context.DefineIdentifier(Name, true))
                {
                    throw new MondCompilerException(this, CompilerError.IdentifierAlreadyDefined, Name);
                }

                identifier = context.Identifier(Name);
            }

            // compile body
            var functionContext = context.MakeFunction(Name ?? DebugName);

            functionContext.Function(functionContext.FullName);
            functionContext.Position(Token);
            functionContext.PushScope();

            for (var i = 0; i < Arguments.Count; i++)
            {
                var name = Arguments[i];

                if (!functionContext.DefineArgument(i, name))
                {
                    throw new MondCompilerException(this, CompilerError.IdentifierAlreadyDefined, name);
                }
            }

            if (OtherArguments != null && !functionContext.DefineArgument(Arguments.Count, OtherArguments))
            {
                throw new MondCompilerException(this, CompilerError.IdentifierAlreadyDefined, OtherArguments);
            }

            CompileBody(functionContext);
            functionContext.PopScope();

            // assign result
            var stack = 0;

            context.Position(Token); // debug info
            stack += context.Closure(functionContext.Label);

            if (shouldStore)
            {
                if (!isStatement) // statements should leave nothing on the stack
                {
                    stack += context.Dup();
                }

                if (!shouldBeGlobal)
                {
                    stack += context.Store(identifier);
                }
                else
                {
                    stack += context.LoadGlobal();
                    stack += context.StoreField(context.String(Name));
                }

                if (isStatement)
                {
                    CheckStack(stack, 0);
                    return(stack);
                }
            }

            CheckStack(stack, 1);
            return(stack);
        }
예제 #6
0
 public void Store(IdentifierOperand operand)
 {
     Emit(new Instruction(InstructionType.StLoc, operand));
 }
예제 #7
0
        public IdentifierOperand DefineInternal(string name, bool canHaveMultiple = false)
        {
            name = "#" + name;

            var frameScope = GetFrameScope();
            var id = frameScope._nextId++;

            IdentifierOperand identifier;

            if (canHaveMultiple)
            {
                var n = 0;
                string numberedName;

                while (true)
                {
                    numberedName = string.Format("{0}_{1}", name, n++);

                    if (!IsDefined(numberedName))
                        break;
                }

                identifier = new IdentifierOperand(_localIndex, id, numberedName, false);
                _identifiers.Add(numberedName, identifier);
                return identifier;
            }

            identifier = new IdentifierOperand(_localIndex, id, name, false);
            _identifiers.Add(name, identifier);
            return identifier;
        }