Exemplo n.º 1
0
        public void TestInheritance()
        {
            var dbContextClassDefinition = new ClassDefinition
            {
                Name      = "StoreDbContext",
                BaseClass = "Microsoft.EntityFrameworkCore.DbContext"
            };

            var repositoryInterfaceDefinition = new InterfaceDefinition
            {
                Name       = "ISalesRepository",
                Implements =
                {
                    "IRepository"
                }
            };

            var savingTypeEnum = new EnumDefinition
            {
                Name     = "SavingType",
                BaseType = "int"
            };

            Assert.True(dbContextClassDefinition.HasInheritance);
            Assert.True(dbContextClassDefinition.BaseClass != null);
            Assert.True(dbContextClassDefinition.Implements.Count == 0);

            Assert.True(repositoryInterfaceDefinition.HasInheritance);
            Assert.False(repositoryInterfaceDefinition.Implements.Count == 0);

            Assert.True(savingTypeEnum.HasInheritance);
        }
Exemplo n.º 2
0
        private void ParseInterface(AccessLevel accessLevel)
        {
            Token interfaceKeyword = _lexer.Eat(TokenType.InterfaceKeyword);
            Token name             = _lexer.Eat(TokenType.Identifer);

            if (accessLevel != AccessLevel.Public)
            {
                accessLevel = AnalysisAccessLevel(name.Content);
            }
            Token colon = null, inheritanceToken = null;

            if (_lexer.Match(":"))
            {
                colon            = _lexer.Eat(TokenType.Colon);
                inheritanceToken = _lexer.Eat(TokenType.Identifer);
            }
            InterfaceDefinition interfaceDefinition =
                new InterfaceDefinition(interfaceKeyword, name, colon, inheritanceToken, _endNameSpace, accessLevel);

            _endNameSpace.AddStructure(interfaceDefinition);
            FilesDefinitions[_lexer.FileIndex].Add(interfaceDefinition);
            _parsingStructure = interfaceDefinition;
            ParseChunk(s_interfaceDefinitionOrder, out Token openBrace, out Token closeBrace);
            interfaceDefinition.SetBraces(openBrace, closeBrace);
            _parsingStructure = null;
        }
Exemplo n.º 3
0
        public override AstNode Visit(InterfaceDefinition node)
        {
            // Use the generic scope.
            PseudoScope genScope = node.GetGenericScope();

            if (genScope != null)
            {
                PushScope(genScope);
            }

            // Process the base structures.
            ProcessBases(node);

            // Update the scope.
            PushScope(node.GetScope());

            // Visit his children.
            VisitList(node.GetChildren());

            // Restore the scope.
            PopScope();

            // Pop the generic scope.
            if (genScope != null)
            {
                PopScope();
            }

            return(node);
        }
Exemplo n.º 4
0
        private static List <InterfaceDefinition> GetExistingServiceContractDefinitions(string serviceContractsFolder, ref GenResult result, List <string> exclusions = null)
        {
            var syncInterfaceFiles = Directory.GetFiles(serviceContractsFolder, "I*.*");
            var interfacesToCreate = new List <InterfaceDefinition>();

            foreach (var syncInterface in syncInterfaceFiles)
            {
                var fi         = new FileInfo(syncInterface);
                var fileName   = fi.Name;
                var isExcluded = exclusions != null && exclusions.Any(e => e.Equals(fileName, StringComparison.OrdinalIgnoreCase));

                if (isExcluded)
                {
                    result.Debug($"Skipping file {syncInterface}");
                    continue;
                }

                var serviceContractName = Path.GetFileNameWithoutExtension(fileName);
                result.Debug($"Building definition for {serviceContractName} from {fileName}");
                var idef = new InterfaceDefinition(serviceContractName, fi.FullName)
                {
                    ExistingServiceContractSyntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(fi.FullName))
                };

                result.Debug($"Info definition {Environment.NewLine} {idef}");


                interfacesToCreate.Add(idef);
            }
            return(interfacesToCreate);
        }
Exemplo n.º 5
0
    public async Task Should_fail_if_ActualType_is_not_possible()
    {
        /* Given */
        var schema = await new SchemaBuilder()
                     .Add(@"
interface Character

type Human

type Query
").Build(new SchemaBuildOptions());
        InterfaceDefinition character         = "interface Character";
        ObjectDefinition    humanNotCharacter = "type Human";
        var value   = new object();
        var context = Substitute.For <IResolverContext>();

        context.ExecutionContext.Schema.Returns(schema);
        context.FieldName.Returns("field");
        context.Field.Returns("field: Character");


        var sut = new CompleteValueResult(value, humanNotCharacter);

        /* When */
        var exception =
            await Assert.ThrowsAsync <CompleteValueException>(() => sut.CompleteValueAsync(context).AsTask());

        /* Then */
        Assert.Equal(
            "Cannot complete value for field 'field: Character'. ActualType 'Human' does not implement interface 'Character'",
            exception.Message);
    }
 public override Object Visit(InterfaceDefinition node, Object obj)
 {
     for (int i = 0; i < node.BaseClass.Count; i++)
     {
         TypeExpression typeExpression = this.searchType(node.BaseClass[i], node.Location.Line, node.Location.Column);
         if (typeExpression == null)
         {
             ErrorManager.Instance.NotifyError(new UnknownTypeError(node.BaseClass[i], node.Location));
         }
         else
         {
             InterfaceType interfaze = typeExpression as InterfaceType;
             if (interfaze == null)
             {
                 ErrorManager.Instance.NotifyError(new ExpectedInterfaceError(node.BaseClass[i], node.Location));
             }
             else
             {
                 ((InterfaceType)node.TypeExpr).AddBaseInterface(interfaze, node.Location);
             }
         }
     }
     ((InterfaceType)node.TypeExpr).Members = builtClass(node, obj);
     node.TypeExpr.BuildTypeExpressionString(TypeExpression.MAX_DEPTH_LEVEL_TYPE_EXPRESSION);
     return(null);
 }
Exemplo n.º 7
0
        public void TestInterface1()
        {
            Boo.Lang.Compiler.Ast.Module module = ParseTestCase("interface_1.boo");

            Assert.AreEqual(1, module.Members.Count);

            InterfaceDefinition id = (InterfaceDefinition)module.Members[0];

            Assert.AreEqual("IContentItem", id.Name);

            Assert.AreEqual(5, id.Members.Count);

            Property p = (Property)id.Members[0];

            Assert.AreEqual("Parent", p.Name);
            Assert.AreEqual("IContentItem", ((SimpleTypeReference)p.Type).Name);
            Assert.IsNotNull(p.Getter, "Getter");
            Assert.IsNull(p.Setter, "Setter");

            p = (Property)id.Members[1];
            Assert.AreEqual("Name", p.Name);
            Assert.AreEqual("string", ((SimpleTypeReference)p.Type).Name);
            Assert.IsNotNull(p.Getter, "Getter");
            Assert.IsNotNull(p.Setter, "Setter");

            Method m = (Method)id.Members[2];

            Assert.AreEqual("SelectItem", m.Name);
            Assert.AreEqual("IContentItem", ((SimpleTypeReference)m.ReturnType).Name);
            Assert.AreEqual("expression", m.Parameters[0].Name);
            Assert.AreEqual("string", ((SimpleTypeReference)m.Parameters[0].Type).Name);

            Assert.AreEqual("Validate", ((Method)id.Members[3]).Name);
            Assert.AreEqual("OnRemove", ((Method)id.Members[4]).Name);
        }
Exemplo n.º 8
0
 override public void LeaveInterfaceDefinition(InterfaceDefinition node)
 {
     CheckMemberName(node);
     CantBeMarkedAbstract(node);
     CantBeMarkedTransient(node);
     CantBeMarkedPartial(node);
 }
Exemplo n.º 9
0
 override public void OnInterfaceDefinition(InterfaceDefinition node)
 {
     if (null != node.Entity)
     {
         return;
     }
     node.Entity = new InternalInterface(TypeSystemServices, node);
 }
Exemplo n.º 10
0
 protected override void EnterInterfaceDefinition(PrinterContext context, InterfaceDefinition interfaceDefinition)
 {
     context.Append(' ');
     context.AppendDescription(interfaceDefinition.Description);
     context.Append("interface ");
     context.Append(interfaceDefinition.Name);
     context.Append(" ");
 }
Exemplo n.º 11
0
 override public void LeaveInterfaceDefinition(InterfaceDefinition node)
 {
     CantBeMarkedAbstract(node);
     CantBeMarkedTransient(node);
     CantBeMarkedPartialIfNested(node);
     CantBeMarkedFinal(node);
     CantBeMarkedStatic(node);
 }
Exemplo n.º 12
0
        internal static RedwoodType Make(InterfaceDefinition @interface)
        {
            RedwoodType type = new RedwoodType();

            type.Name        = @interface.Name;
            type.IsInterface = true;
            return(type);
        }
Exemplo n.º 13
0
        public override void Switch(IAstTransformer transformer, out Node resultingNode)
        {
            InterfaceDefinition thisNode           = (InterfaceDefinition)this;
            InterfaceDefinition resultingTypedNode = thisNode;

            transformer.OnInterfaceDefinition(thisNode, ref resultingTypedNode);
            resultingNode = resultingTypedNode;
        }
Exemplo n.º 14
0
    public IEnumerable<TypeDefinition> GetPossibleTypes(InterfaceDefinition abstractType)
    {
        foreach (var objectDefinition in QueryTypes<ObjectDefinition>(ob => ob.HasInterface(abstractType.Name)))
            yield return objectDefinition;

        foreach (var interfaceDefinition in QueryTypes<InterfaceDefinition>(ob => ob.HasInterface(abstractType.Name)))
            yield return interfaceDefinition;
    }
        public async Task GenericConstraintsReturnsEmptyWhenNoConstraintsDeclared()
        {
            var node = await TestNode.FindNode <InterfaceDeclarationSyntax>(TypeDefinitionCode.InterfaceWithoutParent)
                       .ConfigureAwait(false);

            var actual = new InterfaceDefinition(node);

            actual.GenericConstraints.Should().BeEmpty();
        }
Exemplo n.º 16
0
        public override Object Visit(InterfaceDefinition node, Object obj)
        {
            for (int i = 0; i < node.MemberCount; i++)
            {
                node.GetMemberElement(i).Accept(this, obj);
            }

            return(null);
        }
 public override object Visit(InterfaceDefinition node, object obj)
 {
     if (node.Location == ((AstNode)obj).Location || found)
     {
         found = true;
         return(this.table);
     }
     return(base.Visit(node, obj));
 }
Exemplo n.º 18
0
        internal static UserDefinedType CreateInterface(BaseTypeDeclarationSyntax node, ISyntaxEntity parent, CodeFile currentCodeFile, SyntaxTree tree)
        {
            UserDefinedType typeObj = new InterfaceDefinition(node.Identifier.Text, new FileSpan(tree.GetLineSpan(node.Span)), parent, currentCodeFile);

            processModifiers(typeObj, node.Modifiers);
            typeObj.AccessSpecifiers  = typeObj.AccessSpecifiers == AccessSpecifiers.None ? AccessSpecifiers.Internal : typeObj.AccessSpecifiers;
            typeObj.AssociatedComment = GetComment(typeObj, node, tree, currentCodeFile);

            return(typeObj);
        }
        public override void OnInterfaceDefinition(InterfaceDefinition node)
        {
            if (WasVisited(node))
            {
                return;
            }
            MarkVisited(node);

            base.OnInterfaceDefinition(node);
        }
Exemplo n.º 20
0
    private void VisitInterfaceDefinition(InterfaceDefinition node)
    {
        EnterNode(node);

        Visit(node.Interfaces);
        Visit(node.Directives);
        Visit(node.Fields);

        ExitNode(node);
    }
Exemplo n.º 21
0
            private void ExtractInterface(Cci.INamedTypeDefinition typedef)
            {
                var name = typedef.Name.Value;
                var type = new InterfaceDefinition(name);

                this.ExtractGenericParameters(type.GenericParameters, typedef.GenericParameters);
                this.ExtractInterfaces(type.Interfaces, typedef.Interfaces);
                this.ExtractMethods(type.Methods, typedef.Methods);

                types.Add(name, type);
            }
Exemplo n.º 22
0
 void CheckInterfaceBaseTypes(InterfaceDefinition node)
 {
     foreach (TypeReference baseType in node.BaseTypes)
     {
         IType tag = GetType(baseType);
         if (!tag.IsInterface)
         {
             Error(CompilerErrorFactory.InterfaceCanOnlyInheritFromInterface(baseType, node.FullName, tag.FullName));
         }
     }
 }
Exemplo n.º 23
0
 void CheckInterfaceBaseTypes(InterfaceDefinition node)
 {
     foreach (var baseTypeRef in node.BaseTypes)
     {
         var baseType = GetType(baseTypeRef);
         if (!baseType.IsInterface)
         {
             Error(CompilerErrorFactory.InterfaceCanOnlyInheritFromInterface(baseTypeRef, GetType(node), baseType));
         }
     }
 }
        public async Task ModifiersReturnsExpectedValue(string modifiers, InterfaceModifiers expected)
        {
            var code = TypeDefinitionCode.EmptyInterface.Replace("public interface MyInterface",
                                                                 "public " + modifiers + " interface MyInterface");

            var node = await TestNode.FindNode <InterfaceDeclarationSyntax>(code)
                       .ConfigureAwait(false);

            var sut = new InterfaceDefinition(node);

            sut.Modifiers.Should().Be(expected);
        }
        public async Task CanCreateFromDeclarationNode()
        {
            var node = await TestNode.FindNode <InterfaceDeclarationSyntax>(TypeDefinitionCode.EmptyInterface)
                       .ConfigureAwait(false);

            var sut = new InterfaceDefinition(node);

            sut.Name.Should().Be("MyInterface");
            sut.Namespace.Should().Be("MyNamespace");
            sut.DeclaringType.Should().BeNull();
            sut.ChildClasses.Should().BeEmpty();
        }
    public static bool TryGetDirective(
        this InterfaceDefinition definition,
        Name directiveName,
        [NotNullWhen(true)] out Directive?directive)
    {
        if (definition.Directives is null)
        {
            directive = null;
            return(false);
        }

        return(definition.Directives.TryGet(directiveName, out directive));
    }
        public void WithDescription()
        {
            /* Given */
            InterfaceDefinition original = @"interface Inf";

            /* When */
            var modified = original
                           .WithDescription("Description");

            /* Then */
            Assert.Null(original.Description);
            Assert.Equal("Description", modified.Description);
        }
        public void FromString()
        {
            /* Given */
            /* When */
            InterfaceDefinition original =
                @"interface Inf {
                    field1: String
                }";

            /* Then */
            Assert.Equal("Inf", original.Name);
            Assert.NotNull(original.Fields);
        }
        public void WithName()
        {
            /* Given */
            InterfaceDefinition original = @"interface Inf";

            /* When */
            var modified = original
                           .WithName("Renamed");

            /* Then */
            Assert.Equal("Inf", original.Name);
            Assert.Equal("Renamed", modified.Name);
        }
        public void FromBytes()
        {
            /* Given */
            /* When */
            InterfaceDefinition original =
                Encoding.UTF8.GetBytes(@"interface Inf {
                    field1: String
                }").AsReadOnlySpan();

            /* Then */
            Assert.Equal("Inf", original.Name);
            Assert.NotNull(original.Fields);
        }
Exemplo n.º 31
0
        internal object Interpret(AstNode inputNode, CodeContext context)
        {
            AstNode node = inputNode;	//The next node to be evaluated
            var flow_manager = new InterpreterFlowManager();

            try{
                while(true){
                MAIN_LOOP:	//sub-expressionを評価する必要があるノードの飛び先
                    switch(node.Type){
                    case NodeType.Argument:
                        node = ((ParameterDeclaration)node).Option;
                        goto MAIN_LOOP;

                    case NodeType.Assignment:
                    {
                        var assignment = (AssignmentExpression)node;
                        if(!flow_manager.IsEvaluating(assignment)){		//まず右辺値を評価する
                            flow_manager.Push(assignment);
                            node = assignment.Right;
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();

                            ExpressoTuple rhs = (ExpressoTuple)flow_manager.PopValue();
                            for(int i = 0; i < assignment.Left.Length; ++i){		//その後左辺値に代入する
                                var seq = (SequenceExpression)assignment.Left[i];

                                for(int j = 0; j < rhs.Count; ++j){
                                    var assignable = seq.Items[j] as Assignable;
                                    if(assignable == null)
                                        throw ExpressoOps.MakeRuntimeError("{0} is not an assignable reference.", seq.Items[j]);

                                    assignable.Assign(flow_manager.Top(), rhs[j]);
                                }
                            }
                        }
                        break;
                    }

                    case NodeType.BinaryExpression:
                    {
                        var binary_op = (BinaryExpression)node;
                        if(!flow_manager.IsEvaluating(binary_op))
                            flow_manager.Push(binary_op);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = binary_op.Left;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                            node = binary_op.Right;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 2:
                            flow_manager.Pop();

                            object rhs = flow_manager.PopValue(), lhs = flow_manager.PopValue();
                            if(lhs == null || rhs == null)
                                throw ExpressoOps.MakeRuntimeError("Can not apply the operation on null objects.");

                            object ret = null;
                            if((int)binary_op.Operator <= (int)OperatorType.Modulus){
                                if(lhs is int)
                                    ret = BinaryExprAsInt((int)lhs, (int)rhs, binary_op.Operator);
                                else if(lhs is double)
                                    ret = BinaryExprAsDouble((double)lhs, (double)rhs, binary_op.Operator);
                                else if(lhs is Fraction)
                                    ret = BinaryExprAsFraction((Fraction)lhs, rhs, binary_op.Operator);
                                else
                                    ret = BinaryExprAsString((string)lhs, rhs, binary_op.Operator);
                            }else if((int)binary_op.Operator < (int)OperatorType.ConditionalAnd){
                                ret = EvalComparison(lhs as IComparable, rhs as IComparable, binary_op.Operator);
                            }else if((int)binary_op.Operator < (int)OperatorType.BitwiseOr){
                                ret = EvalLogicalOperation((bool)lhs, (bool)rhs, binary_op.Operator);
                            }else{
                                ret = EvalBitOperation((int)lhs, (int)rhs, binary_op.Operator);
                            }
                            flow_manager.PushValue(ret);
                            break;
                        }
                        break;
                    }

                    case NodeType.Block:
                    {
                        var block = (BlockStatement)node;
                        if(!flow_manager.IsEvaluating(block))
                            flow_manager.Push(block);

                        if(flow_manager.Top().ChildCounter < block.Statements.Count){
                            node = block.Statements[flow_manager.Top().ChildCounter++];
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();
                        }
                        break;
                    }

                    case NodeType.BreakStatement:
                    {
                        var break_stmt = (BreakStatement)node;
                        for(int i = break_stmt.Count; i > 0;){		//Count階層分ループを遡るまで出会ったbreakableをノードスタックから取り除く
                            AstNode popped = flow_manager.Pop().TargetNode;
                            if(popped.Type == NodeType.ForStatement || popped.Type == NodeType.WhileStatement)
                                --i;
                        }
                        break;
                    }

                    case NodeType.Call:
                    {
                        var call = (CallExpression)node;
                        if(!flow_manager.IsEvaluating(call))
                            flow_manager.Push(call);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = call.Target;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                            var fn = flow_manager.Top().Get(0) as FunctionDeclaration;
                            if(flow_manager.Top().ChildCounter < fn.Parameters.Length){	//実引数を評価してスタックに積む
                                var index = flow_manager.Top().ChildCounter++;
                                var param = fn.Parameters[index];
                                node = (index < call.Arguments.Length) ? call.Arguments[index] : param;
                                goto MAIN_LOOP;
                            }

                            flow_manager.Top().Remove(0);	//呼び出す関数オブジェクトをスタックから除く
                            node = fn.Body;
                            flow_manager.Top().StepCounter = fn.HasReturn ? 2 : 3;
                            goto MAIN_LOOP;

                        case 2:
                            var ret = flow_manager.PopValue();
                            flow_manager.Top().Clear();		//関数呼び出しに使ったスタック領域を解放する
                            flow_manager.PushValue(ret);
                            flow_manager.Pop();
                            break;

                        case 3:
                            flow_manager.Top().Clear();		//関数呼び出しに使ったスタック領域を解放する
                            flow_manager.Pop();
                            break;
                        }
                        break;
                    }

                    case NodeType.CaseClause:
                    {
                        var case_clause = (MatchPatternClause)node;
                        if(!flow_manager.IsEvaluating(case_clause))
                            flow_manager.Push(case_clause);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            if(flow_manager.Top().ChildCounter < case_clause.Patterns.Length){
                                node = case_clause.Patterns[flow_manager.Top().ChildCounter++];
                                goto MAIN_LOOP;
                            }else{
                                flow_manager.PushValue(false);
                                flow_manager.Pop();
                            }
                            break;

                        case 1:
                            var label_obj = flow_manager.PopValue();
                            var target = flow_manager.TopValue();
                            if(target is int && label_obj is ExpressoIntegerSequence){
                                var int_seq = (ExpressoIntegerSequence)label_obj;
                                if(int_seq.Includes((int)target)){
                                    node = case_clause.Body;
                                    flow_manager.Top().StepCounter++;
                                    goto MAIN_LOOP;
                                }else{
                                    flow_manager.Top().StepCounter--;
                                }
                            }else if(label_obj is LiteralExpression && ((LiteralExpression)label_obj).Type == ObjectTypes._CASE_DEFAULT){
                                node = case_clause.Body;
                                flow_manager.Top().StepCounter++;
                                goto MAIN_LOOP;
                            }else if(label_obj != null && label_obj.Equals(target)){
                                node = case_clause.Body;
                                flow_manager.Top().StepCounter++;
                                goto MAIN_LOOP;
                            }else{
                                flow_manager.Top().StepCounter--;
                            }
                            break;

                        case 2:
                            flow_manager.Pop();
                            flow_manager.PushValue(true);
                            break;
                        }

                        break;
                    }

                    case NodeType.CastExpression:
                    {
                        var cast_expr = (CastExpression)node;
                        if(!flow_manager.IsEvaluating(cast_expr))
                            flow_manager.Push(cast_expr);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = cast_expr.Target;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                            node = cast_expr.ToExpression;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 2:
                            flow_manager.Pop();

                            var to_expr = flow_manager.PopValue();
                            var target = flow_manager.PopValue();
                            break;
                        }
                        break;
                    }

                    case NodeType.CatchClause:
                    {
                        var catch_clause = (CatchClause)node;
                        var exception = flow_manager.TopValue() as ExpressoThrowException;
                        if(exception == null){
                            throw ExpressoOps.MakeSystemError("The top value of stack is not an exception.");
                        }else if(catch_clause.Catcher.ParamType.TypeName == exception.Thrown.Name){
                            node = catch_clause.Body;
                            goto case NodeType.Block;
                        }
                        break;
                    }

                    case NodeType.Comprehension:  //TODO:実装する
                    {
                        break;
                    }

                    case NodeType.ComprehensionFor:
                    {
                        break;
                    }

                    case NodeType.ComprehensionIf:
                    {
                        var comp_if = (ComprehensionIfClause)node;
                        if(!flow_manager.IsEvaluating(comp_if))
                            flow_manager.Push(comp_if);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = comp_if.Condition;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                            var cond = flow_manager.TopValue();
                            if(!(cond is bool))
                                throw ExpressoOps.MakeInvalidTypeError("Can not evaluate the expression to a boolean.");

                            if((bool)cond){
                                var yield_expr = flow_manager.Top().Get(0) as Expression;
                                node = (comp_if.Body == null) ? yield_expr : comp_if.Body;
                                flow_manager.Pop();
                                goto MAIN_LOOP;
                            }else{
                                flow_manager.Pop();
                            }
                            break;
                        }

                        break;
                    }

                    case NodeType.ConditionalExpression:
                    {
                        var cond_expr = (ConditionalExpression)node;
                        if(!flow_manager.IsEvaluating(cond_expr)){
                            node = cond_expr.Condition;
                            flow_manager.Push(cond_expr);
                        }else{
                            flow_manager.Pop();
                            node = (bool)flow_manager.PopValue() ? cond_expr.TrueExpression : cond_expr.FalseExpression;
                        }
                        goto MAIN_LOOP;
                    }

                    case NodeType.Constant:
                        flow_manager.PushValue(((LiteralExpression)node).Value);
                        break;

                    case NodeType.ContinueStatement:
                    {
                        var continue_stmt = (ContinueStatement)node;
                        for(int i = continue_stmt.Count; i > 0;){		//Count階層分ループを遡るまで出会ったbreakableをノードスタックから取り除く
                            AstNode popped = flow_manager.Pop().TargetNode;
                            if(popped.Type == NodeType.ForStatement || popped.Type == NodeType.WhileStatement &&
                               i != 1)				//continueすべきループはスタックから外さない
                                --i;
                        }
                        break;
                    }

                    case NodeType.DefaultExpression:
                    {
                        var default_expr = (DefaultExpression)node;
                        flow_manager.PushValue(ExpressoOps.GetDefaultValueFor(default_expr.TargetType.ObjType));
                        break;
                    }

                    case NodeType.ExprStatement:
                    {
                        var expr_stmt = (ExpressionStatement)node;
                        if(!flow_manager.IsEvaluating(expr_stmt))
                            flow_manager.Push(expr_stmt);

                        if(flow_manager.Top().ChildCounter < expr_stmt.Expressions.Length){
                            node = expr_stmt.Expressions[flow_manager.Top().ChildCounter++];
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();
                        }
                        break;
                    }

                    case NodeType.FinallyClause:
                    {
                        var finally_clause = (FinallyClause)node;
                        node = finally_clause.Body;
                        goto case NodeType.Block;
                    }

                    case NodeType.ForStatement:
                    {
                        var for_stmt = (ForStatement)node;
                        if(!flow_manager.IsEvaluating(for_stmt))
                            flow_manager.Push(for_stmt);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = for_stmt.Target;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                        {
                            object iterable = flow_manager.TopValue();
                            if(!(iterable is IEnumerable))
                                throw ExpressoOps.MakeInvalidTypeError("Can not evaluate the expression to an iterable object!");

                            Identifier[] lvalues = new Identifier[for_stmt.Left.Count];
                            for(int i = 0; i < for_stmt.Left.Count; ++i){
                                lvalues[i] = for_stmt.Left.Items[i] as Identifier;
                                if(lvalues[i] == null)
                                    throw ExpressoOps.MakeReferenceError("The left-hand-side of the \"in\" keyword must be a lvalue(a referencible value such as variables)");
                            }
                            flow_manager.PushValue(lvalues);
                            flow_manager.Top().StepCounter++;
                            goto case 2;
                        }

                        case 2:
                            Identifier[] lhs = (Identifier[])flow_manager.TopValue();
                            object iterable_obj = flow_manager.GetValue(flow_manager.ValueCount - 2);
                            var rvalue = ExpressoOps.Enumerate(iterable_obj);
                            if(rvalue.MoveNext()){
                                for(int j = 0; j < lhs.Length; ++j){
                                    lhs[j].Assign(flow_manager.Top(), rvalue.Current);
                                    if(j + 1 != lhs.Length){
                                        if(!rvalue.MoveNext())
                                            throw ExpressoOps.MakeRuntimeError("The number of rvalues must be some multiple of that of lvalues.");
                                    }
                                }

                                node = for_stmt.Body;
                                goto MAIN_LOOP;
                            }else{
                                flow_manager.Pop();
                            }
                            break;
                        }
                        break;
                    }

                    case NodeType.FunctionDef:
                        //node = ((FunctionDefinition)node).Body;
                        //goto MAIN_LOOP;
                        flow_manager.PushValue(node);
                        break;

                    case NodeType.Identifier:
                    {
                        var ident = (Identifier)node;
                        if(ident.Type.ObjType == ObjectTypes._Subscript){
                            flow_manager.PushValue(ident);
                        }else if(ident.IsResolved){
                            flow_manager.Top().Dup(ident.Offset);
                        }else if(ident.ParamType.ObjType == ObjectTypes.TypeClass){
                            var cur_module = flow_manager.Top().Get(0) as ExpressoObj;
                            if(cur_module == null)
                                throw ExpressoOps.MakeRuntimeError("\"this\" doesn't refer to the enclosing class instance.");

                            flow_manager.PushValue(cur_module.AccessMember(ident, true));
                        }else if(ident.ParamType.ObjType == ObjectTypes.TypeModule){
                            var module = context.LanguageContext.GetModule(ident.Name);
                            if(module == null)
                                throw ExpressoOps.MakeRuntimeError(string.Format("The requested module \"{0}\" doesn't exist.", ident.Name));

                            flow_manager.PushValue(module);
                        }

                        break;
                    }

                    case NodeType.IfStatement:
                    {
                        var if_stmt = (IfStatement)node;
                        if(!flow_manager.IsEvaluating(if_stmt)){
                            node = if_stmt.Condition;
                            flow_manager.Push(if_stmt);
                        }else{
                            flow_manager.Pop();

                            node = (bool)flow_manager.PopValue() ? if_stmt.TrueBlock : if_stmt.FalseBlock;
                        }
                        goto MAIN_LOOP;
                    }

                    case NodeType.Initializer:
                    {
                        var initializer = (SequenceInitializer)node;
                        if(!flow_manager.IsEvaluating(initializer))
                            flow_manager.Push(initializer);

                        if(flow_manager.Top().ChildCounter < initializer.Items.Length){
                            node = initializer.Items[flow_manager.Top().ChildCounter++];
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();

                            switch(initializer.ObjectType){
                            case ObjectTypes.List:
                            {
                                var values = new List<object>(initializer.Items.Length);
                                for(int i = initializer.Items.Length; i > 0; --i)
                                    values.Add(flow_manager.PopValue());

                                values.Reverse();	//スタックからポップした順番では、逆順になってしまうので、順序を入れ替える
                                flow_manager.PushValue(ExpressoOps.MakeList(values));
                                break;
                            }

                            case ObjectTypes.Tuple:
                            {
                                var values = new List<object>(initializer.Items.Length);
                                for(int i = initializer.Items.Length; i > 0; --i)
                                    values.Add(flow_manager.PopValue());

                                values.Reverse();	//スタックからポップした順番では、逆順になってしまうので、順序を入れ替える
                                flow_manager.PushValue(ExpressoOps.MakeTuple(values));
                                break;
                            }

                            case ObjectTypes.Dict:
                            {
                                var keys = new List<object>(initializer.Items.Length / 2);
                                var values = new List<object>(initializer.Items.Length / 2);
                                for(int i = initializer.Items.Length; i > 0; --i){
                                    if(i % 2 == 1)
                                        keys.Add(flow_manager.PopValue());
                                    else
                                        values.Add(flow_manager.PopValue());
                                }
                                keys.Reverse();     //スタックからポップした順番では逆順になってしまうので、順序を入れ替える
                                values.Reverse();
                                flow_manager.PushValue(ExpressoOps.MakeDict(keys, values));
                                break;
                            }

                            default:
                                throw ExpressoOps.MakeRuntimeError("Unknown type of initializer!");
                            }
                        }
                        break;
                    }

                    case NodeType.MemRef:
                    {
                        var mem_ref = (MemberReference)node;
                        if(!flow_manager.IsEvaluating(mem_ref))
                            flow_manager.Push(mem_ref);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = mem_ref.Target;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                            node = mem_ref.Subscription;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 2:
                            flow_manager.Pop();

                            var subscription = flow_manager.PopValue();
                            var obj = flow_manager.PopValue();
                            if(subscription is ExpressoIntegerSequence){
                                var seq = (ExpressoIntegerSequence)subscription;
                                flow_manager.PushValue(ExpressoOps.Slice(obj, seq));
                            }else if(obj is ExpressoObj){
                                var exs_obj = (ExpressoObj)obj;
                                var member = exs_obj.AccessMember(subscription, obj == flow_manager.Top().Get(0));
                                flow_manager.PushValue(member);
                            }else{
                                var member = ExpressoOps.AccessMember(obj, subscription);
                                flow_manager.PushValue(member);
                            }
                            break;

                        default:
                            throw ExpressoOps.MakeSystemError("Unknown path reached while evaluating a member reference expression!");
                        }
                        break;
                    }

                    case NodeType.Toplevel:
                    {
                        var toplevel = (ExpressoAst)node;
                        if(!flow_manager.IsEvaluating(toplevel))
                            flow_manager.Push(toplevel);

                        if(flow_manager.Top().ChildCounter < toplevel.Body.Length){
                            node = toplevel.Body[flow_manager.Top().ChildCounter++];
                            goto MAIN_LOOP;
                        }else{
                            if(toplevel.IsModule){
                                var internals = new Dictionary<string, int>();
                                var exported = new Dictionary<string, int>();
                                Dictionary<string, int> decl_target = null;
                                var members = new List<object>();
                                int offset = 0;

                                for(int i = 0; i < toplevel.Body.Length; ++i){
                                    decl_target = toplevel.ExportMap.Get(i) ? exported : internals;
                                    var stmt = toplevel.Body[i];
                                    object val = flow_manager.Top().Get(offset);

                                    if(stmt is ExpressionStatement){
                                        var expr_stmt = (ExpressionStatement)stmt;
                                        if(expr_stmt.Expressions[0] is VariableDeclarationStatement){
                                            var var_decls = (VariableDeclarationStatement)expr_stmt.Expressions[0];

                                            for(int j = 0; j < var_decls.Left.Length; ++j){
                                                val = flow_manager.Top().Get(offset);
                                                decl_target.Add(var_decls.Left[j].Name, offset++);
                                                members.Add(val);
                                                //val = flow_manager.Top().Get(offset);
                                                //varStore.Add(var_decls.Variables[i].Offset, obj);	//モジュールスコープの変数ストアにも実体を追加しておく
                                            }
                                        }else{
                                            throw ExpressoOps.MakeInvalidTypeError("A module declaration can not have that type of statements!");
                                        }
                                    }else if(stmt is FunctionDeclaration){
                                        var method = (FunctionDeclaration)stmt;
                                        decl_target.Add(method.Name, offset++);
                                        members.Add(val);
                                    }else if(stmt is TypeDefinition){
                                        var type_decl = (TypeDefinition)stmt;
                                        var type_def = flow_manager.Top().Get(offset);
                                        decl_target.Add(type_decl.Name, offset++);
                                        members.Add(type_def);
                                    }else{
                                        throw ExpressoOps.MakeInvalidTypeError("A module declaration can not have that type of statements!");
                                    }
                                }

                                var module_def = new ModuleDefinition(toplevel.ModuleName, internals, exported, members.ToArray());
                                var module_inst = new ExpressoModule(module_def);
                                context.LanguageContext.PublishModule(toplevel.ModuleName, module_inst);
                            }

                            flow_manager.Pop();
                        }
                        break;
                    }

                    case NodeType.New:
                    {
                        var new_expr = (NewExpression)node;
                        if(!flow_manager.IsEvaluating(new_expr)){
                            node = new_expr.CreationExpression;
                            flow_manager.Push(new_expr);
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();

                            var type_def = flow_manager.PopValue() as BaseDefinition;
                            if(type_def == null)
                                throw ExpressoOps.MakeInvalidTypeError("{0} doesn't refer to a type name.", new_expr.CreationExpression);

                            flow_manager.PushValue(ExpressoObj.CreateInstance(null, type_def, new_expr.Arguments));
                        }
                        break;
                    }

                    case NodeType.Print:
                    {
                        var print_stmt = (PrintStatement)node;
                        if(!flow_manager.IsEvaluating(print_stmt))
                            flow_manager.Push(print_stmt);

                        if(flow_manager.Top().ChildCounter < print_stmt.Expressions.Length){
                            node = print_stmt.Expressions[flow_manager.Top().ChildCounter++];
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();

                            var values = new List<object>(print_stmt.Expressions.Length);
                            for(int i = print_stmt.Expressions.Length; i > 0; --i)
                                values.Add(flow_manager.PopValue());

                            ExpressoOps.DoPrint(values, print_stmt.HasTrailing);
                        }
                        break;
                    }

                    case NodeType.Require:
                    {
                        var require_expr = (ImportDeclaration)node;
                        foreach(var module_name in require_expr.ModuleNames){
                            var path = module_name.Replace('.', '/');
                            path += ".exs";
                            path = GetRelativePathToCurrentSource(path);
                            var module_parser = new Parser(new Scanner(path));
                            module_parser.ParsingFileName = module_name;
                            module_parser.Parse();
                            Interpret(module_parser.TopmostAst, context);
                        }

                        break;
                    }

                    case NodeType.Return:
                    {
                        var return_stmt = (ReturnStatement)node;
                        if(return_stmt.Expression != null){
                            if(!flow_manager.IsEvaluating(return_stmt)){
                                flow_manager.Push(return_stmt);
                                node = return_stmt.Expression;
                                goto MAIN_LOOP;
                            }else{
                                flow_manager.Pop();

                                ExpressoTuple ret = (ExpressoTuple)flow_manager.PopValue();
                                if(ret.Count == 1)
                                    flow_manager.PushValue(ret[0]);
                                else
                                    flow_manager.PushValue(ret);
                            }
                        }
                        break;
                    }

                    case NodeType.IntSequence:
                    {
                        var intseq_expr = (IntegerSequenceExpression)node;
                        if(!flow_manager.IsEvaluating(intseq_expr))
                            flow_manager.Push(intseq_expr);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = intseq_expr.Lower;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                            node = intseq_expr.Upper;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 2:
                            node = intseq_expr.Step;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 3:
                            flow_manager.Pop();

                            var step = flow_manager.PopValue();
                            var end = flow_manager.PopValue();
                            var start = flow_manager.PopValue();
                            if(!(start is int) || !(end is int) || !(step is int))
                                throw ExpressoOps.MakeInvalidTypeError("The start, end and step expressions of the IntSeq expression must yield an integer.");

                            flow_manager.PushValue(new ExpressoIntegerSequence((int)start, (int)end, (int)step));
                            break;

                        default:
                            throw ExpressoOps.MakeSystemError("An error occurred while evaluating an IntegerSequence expression.");
                        }
                        break;
                    }

                    case NodeType.Sequence:
                    {
                        var seq_expr = (SequenceExpression)node;
                        if(!flow_manager.IsEvaluating(seq_expr))
                            flow_manager.Push(seq_expr);

                        if(flow_manager.Top().ChildCounter < seq_expr.Count){
                            node = seq_expr.Items[flow_manager.Top().ChildCounter++];
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();

                            var item_values = new object[seq_expr.Count];
                            for(int i = seq_expr.Count - 1; i >= 0; --i)
                                item_values[i] = flow_manager.PopValue();

                            flow_manager.PushValue(ExpressoOps.MakeTuple(item_values));
                        }
                        break;
                    }

                    case NodeType.SwitchStatement:
                    {
                        var switch_stmt = (MatchStatement)node;
                        if(!flow_manager.IsEvaluating(switch_stmt))
                            flow_manager.Push(switch_stmt);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = switch_stmt.Target;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                            if(flow_manager.Top().ChildCounter < switch_stmt.Clauses.Length){
                                if(flow_manager.Top().ChildCounter != 0){
                                    object top = flow_manager.PopValue();
                                    if(top is bool && (bool)top)
                                        goto CLEANUP_SWITCH;
                                }
                                node = switch_stmt.Clauses[flow_manager.Top().ChildCounter++];
                                goto MAIN_LOOP;
                            }else{
                                flow_manager.Pop();
                            }
                        CLEANUP_SWITCH:
                            flow_manager.PopValue();		//caseラベルと照合する値をスタックから外す
                            break;

                        default:
                            throw ExpressoOps.MakeSystemError("Unknown path reached while evaluating a switch statement!");
                        }
                        break;
                    }

                    case NodeType.ThrowStatement:
                    {
                        var throw_stmt = (ThrowStatement)node;
                        if(!flow_manager.IsEvaluating(throw_stmt)){
                            node = throw_stmt.Expression;
                            flow_manager.Push(throw_stmt);
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();
                        }
                        break;
                    }

                    case NodeType.TryStatement:
                    {
                        var try_stmt = (TryStatement)node;
                        if(!flow_manager.IsEvaluating(try_stmt)){
                            node = try_stmt.Body;
                            flow_manager.Push(try_stmt);
                            goto case NodeType.Block;
                        }else{		//ノードスタックのトップがこのtry文だった場合、try文の本体の実行は終わっている
                            var top = flow_manager.TopValue();
                            if(top is ExpressoThrowException){
                                if(try_stmt.Catches != null){
                                    node = try_stmt.Catches[flow_manager.Top().ChildCounter++];
                                    goto case NodeType.CatchClause;
                                }else{
                                    flow_manager.Pop();
                                    while(flow_manager.Count > 0){	//一つ上のtry文にたどり着くまでノードスタックを巻き戻す
                                        flow_manager.Pop();
                                        if(flow_manager.Top().TargetNode.Type == NodeType.TryStatement)
                                            break;	//NOTE: 次のループに入る前に親のノードを参照するので、ここでは何もしない
                                    }

                                    if(flow_manager.Count == 0)	//このtry文を内包するtry文が見つからなかったので、C#側の例外ハンドラに処理を投げる
                                        throw (ExpressoThrowException)top;
                                }
                            }

                            if(try_stmt.FinallyClause != null){
                                node = try_stmt.FinallyClause;
                                if(flow_manager.IsEvaluating(try_stmt))	//finally節を実行したらこのtry文には用はなくなる
                                    flow_manager.Pop();

                                goto case NodeType.FinallyClause;
                            }

                            flow_manager.Pop();		//ここに到達するのはfinally節がなく、try文の本体で例外が発生しなかった場合だけ
                        }
                        break;
                    }

                    case NodeType.TypeDef:
                    {
                        var type_def = (TypeDefinition)node;
                        if(!flow_manager.IsEvaluating(type_def))
                            flow_manager.Push(type_def);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            if(flow_manager.Top().ChildCounter < type_def.Bases.Length){
                                node = type_def.Bases[flow_manager.Top().ChildCounter++];
                                goto MAIN_LOOP;
                            }else{
                                flow_manager.Top().ChildCounter = 0;
                                flow_manager.Top().StepCounter++;
                                goto case 1;
                            }

                        case 1:
                            if(flow_manager.Top().ChildCounter < type_def.Body.Length){
                                node = type_def.Body[flow_manager.Top().ChildCounter++];
                                goto MAIN_LOOP;
                            }else{
                                flow_manager.Top().StepCounter++;
                                goto case 2;
                            }

                        case 2:
                            var private_members = new Dictionary<string, int>();
                            var public_members = new Dictionary<string, int>();
                            var members = new List<object>();
                            int offset = 0;

                            for(int i = 0; i < type_def.Body.Length; ++i){
                                var stmt = type_def.Body[i];
                                object val = flow_manager.Top().Get(offset);

                                if(stmt is ExpressionStatement){
                                    var expr_stmt = (ExpressionStatement)stmt;
                                    if(expr_stmt.Expressions[0] is VariableDeclarationStatement){
                                        var var_decls = (VariableDeclarationStatement)expr_stmt.Expressions[0];

                                        for(int j = 0; j < var_decls.Left.Length; ++j){
                                            val = flow_manager.Top().Get(offset);
                                            if(var_decls.HasFlag(Flags.PrivateAccess))
                                                private_members.Add(var_decls.Left[j].Name, offset++);
                                            else if(var_decls.HasFlag(Flags.PublicAccess))
                                                public_members.Add(var_decls.Left[j].Name, offset++);

                                            members.Add(val);
                                        }
                                    }else{
                                        throw ExpressoOps.MakeInvalidTypeError("A type declaration can not have that type of statements!");
                                    }
                                }else if(stmt is FunctionDeclaration){
                                    var method = (FunctionDeclaration)stmt;
                                    if(method.HasFlag(Flags.PrivateAccess))
                                        private_members.Add(method.Name, offset++);
                                    else if(method.HasFlag(Flags.PublicAccess))
                                        public_members.Add(method.Name, offset++);

                                    members.Add(val);
                                }else{
                                    throw ExpressoOps.MakeInvalidTypeError("A type declaration can not have that type of statements!");
                                }
                            }

                            //継承元の型定義をスタックから参照する
                            var base_definitions = new List<BaseDefinition>();
                            for(int i = 0; i < type_def.Bases.Length; ++i){
                                BaseDefinition base_def = flow_manager.Top().Get(i) as BaseDefinition;
                                if(base_def == null){
                                    throw ExpressoOps.MakeRuntimeError("Something wrong has occurred.\n Could not find base type '{0}'",
                                        type_def.Bases[i].Name);
                                }
                                base_definitions.Add(base_def);
                            }

                            object def_object = null;
                            switch(type_def.TargetType){
                            case DeclType.Interface:
                                def_object = new InterfaceDefinition(type_def.Name, public_members, members.ToArray(), base_definitions);
                                break;

                            case DeclType.Class:
                                def_object = new ClassDefinition(type_def.Name, private_members, public_members, members.ToArray(), base_definitions);
                                break;

                            case DeclType.Struct:
                                def_object = new StructDefinition(type_def.Name, private_members, public_members, members.ToArray(), base_definitions);
                                break;
                            }

                            flow_manager.PushValue(def_object);
                            flow_manager.Pop();
                            break;

                        default:
                            throw ExpressoOps.MakeSystemError("Unknown path reached while evaluating a type definition.");
                        }
                        break;
                    }

                    case NodeType.UnaryExpression:
                    {
                        var unary_op = (UnaryExpression)node;
                        if(!flow_manager.IsEvaluating(unary_op)){
                            node = unary_op.Operand;
                            flow_manager.Push(unary_op);
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();

                            var ope = flow_manager.PopValue();
                            if(ope == null)
                                throw ExpressoOps.MakeInvalidTypeError("Invalid object type!");

                            flow_manager.PushValue(EvalUnaryOperation(unary_op.Operator, ope));
                        }
                        break;
                    }

                    case NodeType.VarDecl:
                    {
                        var var_decl = (VariableDeclarationStatement)node;
                        if(!flow_manager.IsEvaluating(var_decl))
                            flow_manager.Push(var_decl);

                        int child_counter = flow_manager.Top().ChildCounter;
                        if(child_counter < var_decl.Left.Length){
                            node = var_decl.Expressions[flow_manager.Top().ChildCounter++];
                            goto MAIN_LOOP;
                        }else{
                            flow_manager.Pop();
                        }
                        break;
                    }

                    case NodeType.WhileStatement:
                    {
                        var while_stmt = (WhileStatement)node;
                        if(!flow_manager.IsEvaluating(while_stmt))
                            flow_manager.Push(while_stmt);

                        switch(flow_manager.Top().StepCounter){
                        case 0:
                            node = while_stmt.Condition;
                            flow_manager.Top().StepCounter++;
                            goto MAIN_LOOP;

                        case 1:
                            var cond = flow_manager.PopValue();
                            try{
                                if(cond != null && (bool)cond){
                                    node = while_stmt.Body;
                                    flow_manager.Top().StepCounter--;
                                    goto MAIN_LOOP;
                                }else{
                                    flow_manager.Pop();
                                }
                            }
                            catch(Exception){
                                if(!(cond is bool))
                                    throw ExpressoOps.MakeInvalidTypeError("Invalid expression! The condition of a while statement must yield a boolean!");
                            }
                            break;

                        default:
                            throw ExpressoOps.MakeSystemError("Unknown path reached while evaluating a while statement!");
                        }
                        break;
                    }

                    case NodeType.WithStatement:
                        break;

                    case NodeType.YieldStatement:
                        break;

                    default:
                        throw ExpressoOps.MakeRuntimeError("Unknown AST type!");
                    }

                    if(flow_manager.Count != 0)
                        node = flow_manager.Top().TargetNode;
                    else
                        break;		//評価スタックがなくなったので、ループを抜ける
                }
            }
            catch(Exception ex){
                Type exception_type = ex.GetType();
                Console.WriteLine("{0}: {1}", exception_type.FullName, ex.Message);
                Console.WriteLine("Stack trace: {0}", ex.StackTrace);
            }

            Debug.Assert(flow_manager.ValueCount == 0 || flow_manager.ValueCount == 1);
            return (flow_manager.ValueCount > 0) ? flow_manager.PopValue() : null;
        }