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; }
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; }
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; }
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; }
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); }
public void Store(IdentifierOperand operand) { Emit(new Instruction(InstructionType.StLoc, operand)); }
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; }