コード例 #1
0
ファイル: Definition.cs プロジェクト: RainwayApp/bebop
 public FunctionDefinition(string name, Span span, string documentation, ConstDefinition signature, StructDefinition argumentStruct, StructDefinition returnStruct, Definition?parent = null)
     : base(name, span, documentation, parent)
 {
     Signature      = signature;
     ArgumentStruct = argumentStruct;
     ReturnStruct   = returnStruct;
 }
コード例 #2
0
        private static bool CompareType(StructDefinition defn, Type type)
        {
            var fields = type.GetFields();

            if (defn.Members.Count != fields.Length)
            {
                return(false);
            }

            for (var i = 0; i < fields.Length; i++)
            {
                if (fields[i].Name != defn.Members[i].Name)
                {
                    return(false);
                }

                if (fields[i].FieldType.IsArray)
                {
                    var attrs = fields[i].GetCustomAttributes(typeof(SerializationAttribute), true);
                    if (attrs.Length == 0)
                    {
                        throw new InvalidOperationException("Array fields must have a valid SerializationAttribute");
                    }

                    var attr = attrs[0] as SerializationAttribute;
                    if (attr.ArraySize != defn.Members[i].ArraySize)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
コード例 #3
0
 private void GenerateStructMetadata(StructDefinition definition)
 {
     foreach (KeyValuePair <string, DefineVariableNode> field in definition.ContainFields)
     {
         AnalyzeVarDef(field.Value, false);
     }
 }
コード例 #4
0
        private static void TraverseDefinitions(XElement node, List <StructDefinition> list, ref bool inside)
        {
            if (node.Name == "h4")
            {
                if (node.Value == "C Specification")
                {
                    inside = true;
                }
            }
            else if (node.Name == "code")
            {
                if (inside)
                {
                    XAttribute attrClass = node.Attribute("class");
                    if (attrClass != null && attrClass.Value == "language-c++")
                    {
                        string v    = node.Value;
                        var    item = new StructDefinition()
                        {
                            raw = v,
                        };
                        list.Add(item);
                        inside = false;
                    }
                }
            }

            foreach (XElement item in node.Elements())
            {
                TraverseDefinitions(item, list, ref inside);
            }
        }
コード例 #5
0
        public override string GenerateCodeForStruct(StructDefinition structDef)
        {
            if (structDef.NameToken.Value == "Value")
            {
                // I need to do fancy stuff with unions, so special case this one.
                return(this.LoadTextResource("Resources/ValueStruct.txt", new Dictionary <string, string>()));
            }

            StringBuilder sb = new StringBuilder();

            sb.Append("struct ");
            sb.Append(structDef.NameToken.Value);
            sb.Append(" {\n");
            for (int i = 0; i < structDef.ArgNames.Length; ++i)
            {
                string fieldName = structDef.ArgNames[i].Value;
                PType  fieldType = structDef.ArgTypes[i];
                sb.Append('\t');
                sb.Append(this.TranslateType(fieldType));
                sb.Append(' ');
                sb.Append(fieldName);
                sb.Append(";\n");
            }

            sb.Append("};\n\n");

            return(sb.ToString());
        }
コード例 #6
0
 public override void LeaveStructDefinition(StructDefinition node)
 {
     CantBeMarkedAbstract(node);
     CantBeMarkedFinal(node);
     CantBeMarkedStatic(node);
     CantBeMarkedPartial(node);
 }
コード例 #7
0
ファイル: Helpers.cs プロジェクト: Norbyte/lslib
 public object Read(GR2Reader gr2, StructDefinition definition, MemberDefinition member, uint arraySize, object parent)
 {
     var controls = new List<UInt16>((int)arraySize);
     for (int i = 0; i < arraySize; i++)
         controls.Add(gr2.Reader.ReadUInt16());
     return controls;
 }
コード例 #8
0
ファイル: ModuleInheritance.cs プロジェクト: MilkTool/chela
        public override AstNode Visit(StructDefinition node)
        {
            // Fix the vtable.
            try
            {
                node.GetStructure().FixInheritance();
            }
            catch (ModuleException error)
            {
                Error(node, error.Message);
            }

            // Create default constructor.
            CreateDefaultConstructor(node);

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

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

            // Restore the scope.
            PopScope();

            return(node);
        }
コード例 #9
0
        public override AstNode Visit(StructDefinition node)
        {
            // Use the generic scope.
            PseudoScope genScope = node.GetGenericScope();

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

            // Process the base structures.
            node.GetStructure().SetBase(currentModule.GetValueTypeClass());

            // Process the base interfaces.
            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);
        }
コード例 #10
0
 /// <summary>
 /// Generate the body of the <c>encode</c> function for the given <see cref="FieldsDefinition"/>.
 /// </summary>
 /// <param name="definition">The definition to generate code for.</param>
 /// <returns>The generated Dart <c>encode</c> function body.</returns>
 public string CompileEncode(FieldsDefinition definition)
 {
     return(definition switch
     {
         MessageDefinition d => CompileEncodeMessage(d),
         StructDefinition d => CompileEncodeStruct(d),
         _ => throw new InvalidOperationException($"invalid CompileEncode value: {definition}"),
     });
コード例 #11
0
        public void CompileBlobOfCode(string name, string code)
        {
            ICompilationEntity[] entities = this.interpreterParser.ParseText(name, code);
            foreach (ICompilationEntity entity in entities)
            {
                switch (entity.EntityType)
                {
                case CompilationEntityType.FUNCTION:
                    FunctionDefinition fnDef        = (FunctionDefinition)entity;
                    string             functionName = fnDef.NameToken.Value;
                    if (this.FunctionDefinitions.ContainsKey(functionName))
                    {
                        throw new ParserException(fnDef.FirstToken, "Multiple definitions of function: '" + functionName + "'");
                    }
                    this.FunctionDefinitions[functionName] = fnDef;
                    break;

                case CompilationEntityType.STRUCT:
                    StructDefinition structDef  = (StructDefinition)entity;
                    string           structName = structDef.NameToken.Value;
                    if (this.StructDefinitions.ContainsKey(structName))
                    {
                        throw new ParserException(structDef.FirstToken, "Multiple definitions of function: '" + structName + "'");
                    }
                    this.StructDefinitions[structName] = structDef;
                    break;

                case CompilationEntityType.ENUM:
                    EnumDefinition enumDef  = (EnumDefinition)entity;
                    string         enumName = enumDef.NameToken.Value;
                    if (this.EnumDefinitions.ContainsKey(enumName))
                    {
                        throw new ParserException(enumDef.FirstToken, "Multiple definitions of function: '" + enumName + "'");
                    }
                    this.EnumDefinitions[enumName] = enumDef;
                    break;

                case CompilationEntityType.CONSTANT:
                case CompilationEntityType.GLOBAL:
                    VariableDeclaration assignment = (VariableDeclaration)entity;
                    string targetName = assignment.VariableNameToken.Value;
                    Dictionary <string, VariableDeclaration> lookup = entity.EntityType == CompilationEntityType.CONSTANT
                            ? this.ConstantDefinitions
                            : this.Globals;
                    if (lookup.ContainsKey(targetName))
                    {
                        throw new ParserException(
                                  assignment.FirstToken,
                                  "Multiple definitions of : '" + targetName + "'");
                    }
                    lookup[targetName] = assignment;
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
コード例 #12
0
        protected override void VisitStructField(StructDefinition @struct, StructField field)
        {
            base.VisitStructField(@struct, field);

            if (field.FieldType.Name == "bool")
            {
                field.FieldType.Name = "bool_t";
            }
        }
コード例 #13
0
        protected override void VisitStruct(StructDefinition @struct)
        {
            base.VisitStruct(@struct);

            if (@struct.Name.StartsWith("LLVM") && @struct.Name.EndsWith("Ref"))
            {
                @struct.AddAttr(@"System.Diagnostics.DebuggerDisplay(""{Pointer}"")");
            }
        }
コード例 #14
0
 /// <summary>
 /// Generate the body of the <c>encode</c> function for the given <see cref="TopLevelDefinition"/>.
 /// </summary>
 /// <param name="definition">The definition to generate code for.</param>
 /// <returns>The generated CPlusPlus <c>encode</c> function body.</returns>
 public string CompileEncode(TopLevelDefinition definition)
 {
     return(definition switch
     {
         MessageDefinition d => CompileEncodeMessage(d),
         StructDefinition d => CompileEncodeStruct(d),
         UnionDefinition d => CompileEncodeUnion(d),
         _ => throw new InvalidOperationException($"invalid CompileEncode kind: {definition}"),
     });
        public async Task GenericConstraintsReturnsEmptyWhenNoConstraintsDeclared()
        {
            var node = await TestNode.FindNode <StructDeclarationSyntax>(TypeDefinitionCode.StructWithoutParent)
                       .ConfigureAwait(false);

            var actual = new StructDefinition(node);

            actual.GenericConstraints.Should().BeEmpty();
        }
コード例 #16
0
        internal static UserDefinedType CreateStruct(BaseTypeDeclarationSyntax node, ISyntaxEntity parent, CodeFile currentCodeFile, SyntaxTree tree)
        {
            UserDefinedType typeObj = new StructDefinition(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);
        }
コード例 #17
0
 /// <summary>
 /// Write the part within the `pub struct` definition. This will just write the attributes.
 /// </summary>
 private void WriteStructDefinitionAttrs(IndentedStringBuilder builder, StructDefinition d, bool makePub = true)
 {
     foreach (var f in d.Fields)
     {
         WriteDocumentation(builder, f.Documentation);
         WriteDeprecation(builder, f.DeprecatedAttribute);
         var pub = makePub ? "pub " : "";
         builder.AppendLine($"{pub}{MakeAttrIdent(f.Name)}: {TypeName(f.Type)},");
     }
 }
コード例 #18
0
ファイル: TestGenGoRpc.cs プロジェクト: Azure/autorest.go
        private static Tuple <Node, string> GetServerReceiver(string typeName)
        {
            // make sure type is exported
            if (!char.IsUpper(typeName[0]))
            {
                typeName = $"{char.ToUpperInvariant(typeName[0])}{typeName.Substring(1)}";
            }

            return(new Tuple <Node, string>(StructDefinition.Generate(typeName, null), typeName));
        }
コード例 #19
0
        public override void GenerateCodeForStruct(TranspilerContext sb, StructDefinition structDef)
        {
            string name = structDef.NameToken.Value;

            sb.Append("class ");
            sb.Append(name);
            sb.Append(" {");
            sb.Append(this.NewLine);
            sb.TabDepth++;

            string[] localNames = structDef.LocalFieldNames.Select(a => a.Value).ToArray();
            string[] flatNames  = structDef.FlatFieldNames.Select(a => a.Value).ToArray();

            foreach (string fieldName in flatNames)
            {
                sb.Append(sb.CurrentTab);
                sb.Append("var $");
                sb.Append(fieldName);
                sb.Append(';');
                sb.Append(this.NewLine);
            }
            sb.Append(sb.CurrentTab);
            sb.Append("function __construct(");
            for (int i = 0; i < flatNames.Length; ++i)
            {
                if (i > 0)
                {
                    sb.Append(", ");
                }
                sb.Append("$a");
                sb.Append(i);
            }
            sb.Append(") {");
            sb.Append(this.NewLine);
            sb.TabDepth++;
            for (int i = 0; i < flatNames.Length; ++i)
            {
                sb.Append(sb.CurrentTab);
                sb.Append("$this->");
                sb.Append(flatNames[i]);
                sb.Append(" = $a");
                sb.Append(i);
                sb.Append(';');
                sb.Append(this.NewLine);
            }
            sb.TabDepth--;
            sb.Append(sb.CurrentTab);
            sb.Append('}');
            sb.Append(this.NewLine);

            sb.TabDepth--;
            sb.Append(sb.CurrentTab);
            sb.Append('}');
            sb.Append(this.NewLine);
        }
コード例 #20
0
    public static List <PropertyDefinition> GetColumnProperties(StructDefinition structDefinition, bool includeAutoIncrement = true)
    {
        var properties = structDefinition.Properties.Where(x => x.Attributes.Any(a => a.Name == "ColumnAttribute")).ToList();

        if (!includeAutoIncrement)
        {
            properties.RemoveAll(x => x.Attributes.Any(a => a.Name == "IdentityAttribute"));
        }

        return(properties);
    }
コード例 #21
0
ファイル: Parser.cs プロジェクト: falun/crayon
        public void AddStructDefinition(StructDefinition structDefinition)
        {
            if (this.structDefinitions.ContainsKey(structDefinition.Name.Value))
            {
                throw new ParserException(structDefinition.FirstToken, "A struct with this name has already been defined.");
            }

            this.VerifyNameFree(structDefinition.Name);

            this.structDefinitions.Add(structDefinition.Name.Value, structDefinition);
        }
コード例 #22
0
            private void ExtractStruct(Cci.INamedTypeDefinition typedef)
            {
                var name = typedef.Name.Value;
                var type = new StructDefinition(name);

                this.ExtractGenericParameters(type.GenericParameters, typedef.GenericParameters);
                this.ExtractFields(type.Fields, typedef.Fields);
                this.ExtractMethods(type.Methods, typedef.Methods);

                types.Add(name, type);
            }
        public async Task ModifiersReturnsExpectedValue(string modifiers, StructModifiers expected)
        {
            var code = EmptyStruct.Replace("public struct MyStruct", "public " + modifiers + " struct MyStruct");

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

            var sut = new StructDefinition(node);

            sut.Modifiers.Should().Be(expected);
        }
コード例 #24
0
ファイル: PastelCompiler.cs プロジェクト: blakeohare/pastel
 private void ResolveStructTypes()
 {
     foreach (string structName in this.StructDefinitions.Keys.OrderBy(t => t))
     {
         StructDefinition structDef = this.StructDefinitions[structName];
         for (int i = 0; i < structDef.LocalFieldTypes.Length; ++i)
         {
             structDef.LocalFieldTypes[i].FinalizeType(this);
         }
     }
 }
コード例 #25
0
 private void AnalyzeStrurt(StructDefinition definition)
 {
     foreach (KeyValuePair <string, DefineVariableNode> field in definition.ContainFields)
     {
         AnalyzeVarDef(field.Value);
     }
     foreach (KeyValuePair <string, FunctionDefinition> function in definition.ContainFunctions)
     {
         AnalyzeFunction(function.Value);
     }
 }
        public async Task CanCreateFromDeclarationNode()
        {
            var node = await TestNode.FindNode <StructDeclarationSyntax>(EmptyStruct)
                       .ConfigureAwait(false);

            var sut = new StructDefinition(node);

            sut.Name.Should().Be("MyStruct");
            sut.Namespace.Should().Be("MyNamespace");
            sut.DeclaringType.Should().BeNull();
            sut.ChildStructs.Should().BeEmpty();
        }
コード例 #27
0
        private static void ThrowUnknownVertexFormatError(StructDefinition defn)
        {
            string formatDesc = "";

            foreach (var field in defn.Members)
            {
                string format = field.Name + ": " + field.Type.ToString() + "[" + field.ArraySize.ToString() + "]";
                formatDesc += format + Environment.NewLine;
            }

            throw new Exception("The specified vertex format was not recognized. Format descriptor: " + Environment.NewLine + formatDesc);
        }
コード例 #28
0
        public Type SelectType(MemberDefinition member, StructDefinition defn, object parent)
        {
            var fieldName = defn.Members[0].Name;

            if (fieldName.Substring(0, 16) != "CurveDataHeader_")
            {
                throw new ParsingException("Unrecognized curve data header type: " + fieldName);
            }

            var curveType = fieldName.Substring(16);

            return(CurveRegistry.Resolve(curveType));
        }
コード例 #29
0
        public object Read(GR2Reader reader, StructDefinition definition, MemberDefinition member, uint arraySize, object parent)
        {
            VertexDescriptor descriptor;

            if (!VertexTypeCache.TryGetValue(parent, out descriptor))
            {
                descriptor = ConstructDescriptor(member, definition, parent);
                VertexTypeCache.Add(parent, descriptor);
            }

            var vertex = descriptor.CreateInstance();

            vertex.Unserialize(reader);
            return(vertex);
        }
        public async Task GenericConstraintsReturnsDeclaredConstraints()
        {
            var node = await TestNode.FindNode <StructDeclarationSyntax>(TypeDefinitionCode.StructWithGenericConstraints)
                       .ConfigureAwait(false);

            var actual = new StructDefinition(node);

            actual.GenericConstraints.Should().HaveCount(1);

            var constraintList = actual.GenericConstraints.First();

            constraintList.Name.Should().Be("T");
            constraintList.Constraints.First().Should().Be("Stream");
            constraintList.Constraints.Skip(1).First().Should().Be("new()");
        }
コード例 #31
0
        public object Read(GR2Reader reader, StructDefinition definition, MemberDefinition member, uint arraySize, object parent)
        {
            Type type;

            if (!VertexTypeCache.TryGetValue(parent, out type))
            {
                type = SelectType(member, definition, parent);
                VertexTypeCache.Add(parent, type);
            }

            var vertex = Helpers.CreateInstance(type);

            (vertex as Vertex).Unserialize(reader);
            return(vertex);
        }
コード例 #32
0
ファイル: Reader.cs プロジェクト: Norbyte/lslib
        public StructDefinition ReadStructDefinition()
        {
            var defn = new StructDefinition();
            while (true)
            {
                var member = ReadMemberDefinition();
                if (member.IsValid)
                    defn.Members.Add(member);
                else
                    break;
            }

            return defn;
        }
コード例 #33
0
ファイル: Vertex.cs プロジェクト: Norbyte/lslib
        private static bool CompareType(StructDefinition defn, Type type)
        {
            var fields = type.GetFields();
            if (defn.Members.Count != fields.Length)
                return false;

            for (var i = 0; i < fields.Length; i++)
            {
                if (fields[i].Name != defn.Members[i].Name)
                    return false;

                if (fields[i].FieldType.IsArray)
                {
                    var attrs = fields[i].GetCustomAttributes(typeof(SerializationAttribute), true);
                    if (attrs.Length == 0)
                        throw new InvalidOperationException("Array fields must have a valid SerializationAttribute");

                    var attr = attrs[0] as SerializationAttribute;
                    if (attr.ArraySize != defn.Members[i].ArraySize)
                        return false;
                }
            }

            return true;
        }
コード例 #34
0
ファイル: Vertex.cs プロジェクト: Norbyte/lslib
        private static void ThrowUnknownVertexFormatError(StructDefinition defn)
        {
            string formatDesc = "";
            foreach (var field in defn.Members)
            {
                string format = field.Name + ": " + field.Type.ToString() + "[" + field.ArraySize.ToString() + "]";
                formatDesc += format + Environment.NewLine;
            }

            throw new Exception("The specified vertex format was not recognized. Format descriptor: " + Environment.NewLine + formatDesc);
        }
コード例 #35
0
ファイル: Writer.cs プロジェクト: Norbyte/lslib
        public void WriteStructReference(StructDefinition defn)
        {
            if (defn != null)
            {
                AddFixup(defn);

                if (!GR2.Types.ContainsKey(defn.Type))
                {
                    GR2.Types.Add(defn.Type, defn);
                }
            }
            
            if (GR2.Magic.Is32Bit)
                Writer.Write((UInt32)0);
            else
                Writer.Write((UInt64)0);
        }
コード例 #36
0
ファイル: Writer.cs プロジェクト: Norbyte/lslib
        internal void WriteStruct(StructDefinition definition, object node, bool allowRecursion = true)
        {
            if (node == null) throw new ArgumentNullException();

            AlignWrite();
            StoreObjectOffset(node);

            var tag = GR2.Header.tag;
            foreach (var member in definition.Members)
            {
                if (member.ShouldSerialize(tag))
                {
                    var value = member.CachedField.GetValue(node);
                    if (member.SerializationKind == SerializationKind.UserRaw)
                        member.Serializer.Write(this.GR2, this, member, value);
                    else
                        WriteInstance(member, member.CachedField.FieldType, value);
                }
            }

            // When the struct is empty, we need to write a dummy byte to make sure that another 
            // struct won't have the same address.
            if (definition.Members.Count == 0)
            {
                Writer.Write((Byte)0);
            }

            if (Writer == MainWriter && allowRecursion)
            {
                // We need to write all child structs directly after the parent struct
                // (at least this is how granny2.dll does it)
                GR2.FlushPendingWrites();
            }
        }
コード例 #37
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;
        }
コード例 #38
0
ファイル: Vertex.cs プロジェクト: Norbyte/lslib
        public object Read(GR2Reader reader, StructDefinition definition, MemberDefinition member, uint arraySize, object parent)
        {
            Type type;
            if (!VertexTypeCache.TryGetValue(parent, out type))
            {
                type = SelectType(member, definition, parent);
                VertexTypeCache.Add(parent, type);
            }

            var vertex = Helpers.CreateInstance(type);
            (vertex as Vertex).Unserialize(reader);
            return vertex;
        }
コード例 #39
0
ファイル: Writer.cs プロジェクト: Norbyte/lslib
 internal void AddMixedMarshalling(object o, UInt32 count, StructDefinition type)
 {
     var marshal = new MixedMarshallingData();
     marshal.Obj = o;
     marshal.Count = count;
     marshal.Type = type;
     MixedMarshalling.Add(marshal);
 }
コード例 #40
0
ファイル: Writer.cs プロジェクト: Norbyte/lslib
        internal StructDefinition LookupStructDefinition(Type type)
        {
            if (type.GetInterfaces().Contains(typeof(System.Collections.IList)) || type.IsArray || type.IsPrimitive)
                throw new ArgumentException("Cannot create a struct definition for array or primitive types");

            StructDefinition defn = null;
            if (!Types.TryGetValue(type, out defn))
            {
                defn = new StructDefinition();
                Types.Add(type, defn);
                defn.LoadFromType(type, this);
            }

            return defn;
        }
コード例 #41
0
ファイル: Reader.cs プロジェクト: Norbyte/lslib
        private void MixedMarshal(UInt32 count, StructDefinition definition)
        {
            for (var arrayIdx = 0; arrayIdx < count; arrayIdx++)
            {
                foreach (var member in definition.Members)
                {
                    var size = member.Size(this);
                    if (member.Type == MemberType.Inline)
                    {
                        MixedMarshal(member.ArraySize == 0 ? 1 : member.ArraySize, member.Definition.Resolve(this));
                    }
                    else if (member.MarshallingSize() > 1)
                    {
                        var marshalSize = member.MarshallingSize();
                        byte[] data = new byte[size];
                        Stream.Read(data, 0, (int)size);
                        for (var j = 0; j < size / marshalSize; j++)
                        {
                            // Byte swap for 2, 4, 8-byte values
                            for (var off = 0; off < marshalSize / 2; off++)
                            {
                                var tmp = data[j * marshalSize + off];
                                data[j * marshalSize + off] = data[j * marshalSize + marshalSize - 1 - off];
                                data[j * marshalSize + marshalSize - 1 - off] = tmp;
                            }
                        }

                        Stream.Seek(-size, SeekOrigin.Current);
                        Stream.Write(data, 0, (int)size);
                        Stream.Seek(-size, SeekOrigin.Current);
                    }

                    Stream.Seek(size, SeekOrigin.Current);
                }
            }
        }
コード例 #42
0
ファイル: Vertex.cs プロジェクト: Norbyte/lslib
        public static Type FindByStruct(StructDefinition defn)
        {
            Init();

            foreach (var proto in PrototypeMap)
            {
                if (CompareType(defn, proto.Key))
                {
                    return proto.Value;
                }
            }

            ThrowUnknownVertexFormatError(defn);
            return null;
        }
コード例 #43
0
ファイル: Writer.cs プロジェクト: Norbyte/lslib
        public void WriteStructDefinition(StructDefinition defn)
        {
            Debug.Assert(Writer == MainWriter);
            GR2.ObjectOffsets[defn] = new SectionReference(Type, (UInt32)MainStream.Position);

            var tag = GR2.Header.tag;
            foreach (var member in defn.Members)
            {
                if (member.ShouldSerialize(tag))
                {
                    WriteMemberDefinition(member);
                }
            }

            var end = new MemberDefinition();
            end.Type = MemberType.None;
            end.Extra = new UInt32[] { 0, 0, 0 };
            WriteMemberDefinition(end);
        }
コード例 #44
0
ファイル: Reader.cs プロジェクト: Norbyte/lslib
        internal object ReadStruct(StructDefinition definition, MemberType memberType, object node, object parent)
        {
            var offset = (UInt32)Stream.Position;
            object cachedNode = null;
            if (memberType != MemberType.Inline && CachedStructs.TryGetValue(offset, out cachedNode))
            {
#if DEBUG_GR2_SERIALIZATION
                System.Console.WriteLine(String.Format("Skipped cached struct {1} at {0:X8}", offset, node.ToString()));
#endif
                Stream.Position += definition.Size(this);
                return cachedNode;
            }

            if (node != null)
            {
                // Don't save inline structs in the cached struct map, as they can occupy the same address as a non-inline struct
                // if they're at the beginning of said struct.
                // They also cannot be referenced from multiple locations, so caching them is of no use.
                if (memberType != MemberType.Inline)
                    CachedStructs.Add(offset, node);

#if DEBUG_GR2_FORMAT_DIFFERENCES
                // Create a struct definition from this instance and check if the GR2 type differs from the local type.
                var localDefn = new StructDefinition();
                localDefn.LoadFromType(node.GetType(), null);

                var localMembers = localDefn.Members.Where(m => m.ShouldSerialize(Header.tag)).ToList();
                var defnMembers = definition.Members.Where(m => m.ShouldSerialize(Header.tag)).ToList();

                if (localMembers.Count != defnMembers.Count)
                {
                    Trace.TraceWarning(String.Format("Struct {0} differs: Field count differs ({1} vs {2})", node.GetType().Name, localMembers.Count, defnMembers.Count));
                }
                else
                {
                    for (int i = 0; i < localMembers.Count; i++)
                    {
                        var member = localMembers[i];
                        var local = defnMembers[i];
                        if (member.Type != local.Type)
                        {
                            Trace.TraceWarning(String.Format(
                                "Struct {0}: Field {1} type differs ({1} vs {2})",
                                node.GetType().Name, local.Name, local.Type, member.Type
                            ));
                        }

                        if (!member.GrannyName.Equals(local.GrannyName))
                        {
                            Trace.TraceWarning(String.Format(
                                "Struct {0}: Field {1} name differs ({1} vs {2})",
                                node.GetType().Name, local.Name, local.GrannyName, member.GrannyName
                            ));
                        }

                        if (member.ArraySize != local.ArraySize)
                        {
                            Trace.TraceWarning(String.Format(
                                "Struct {0}: Field {1} array size differs ({1} vs {2})",
                                node.GetType().Name, local.Name, local.ArraySize, member.ArraySize
                            ));
                        }
                    }
                }
#endif

                definition.MapType(node);
                foreach (var member in definition.Members)
                {
                    var field = member.LookupFieldInfo(node);
                    if (field != null)
                    {
                        var value = ReadInstance(member, field.GetValue(node), field.FieldType, node);
                        field.SetValue(node, value);
                    }
                    else
                    {
                        ReadInstance(member, null, null, node);
                    }
                }
            }
            else
            {
                foreach (var member in definition.Members)
                {
                    ReadInstance(member, null, null, null);
                }
            }

            return node;
        }
コード例 #45
0
ファイル: Vertex.cs プロジェクト: Norbyte/lslib
 public Type SelectType(MemberDefinition member, StructDefinition defn, object parent)
 {
     return VertexFormatRegistry.FindByStruct(defn);
 }