예제 #1
0
        public int Visit(VarExpression expression)
        {
            _writer.Write(expression.IsReadOnly ? "const " : "var ");

            var first = true;

            foreach (var declaration in expression.Declarations)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    _writer.Write(", ");
                }

                _writer.Write(declaration.Name);

                if (declaration.Initializer != null)
                {
                    _writer.Write(" = ");
                    declaration.Initializer.Accept(this);
                }
            }

            return(0);
        }
예제 #2
0
        private Expression readExpression()
        {
            Console.WriteLine(" 1: Const Expression\n 2: Var Expression\n 3: Arith Expression");
            int c = Convert.ToInt32(Console.ReadLine());

            if (c == 1)
            {
                Console.WriteLine("Input constant expression");
                ConstExpression cx = new ConstExpression(Convert.ToInt32(Console.ReadLine()));
                return((Expression)cx);
            }
            else if (c == 2)
            {
                Console.WriteLine("Input variable expression");
                VarExpression ve = new VarExpression(Console.ReadLine());
                return((Expression)ve);
            }
            else if (c == 3)
            {
                ArithExpression ae = new ArithExpression();
                Console.WriteLine("Input left expression");
                ae.setL(readExpression());
                Console.WriteLine("Input operator");
                ae.setOp(Console.ReadLine()[0]);
                Console.WriteLine("Input right expression");
                ae.setR(readExpression());
                return((Expression)ae);
            }
            return(null);
        }
예제 #3
0
 /// <summary>
 /// Visit VarExpression
 /// </summary>
 /// <param name="expression">VarExpression to check</param>
 public override void Visit(VarExpression expression)
 {
     //Check if expression is assigned to existing variable
     if (!SymbolTable.ContainsVariable(expression.GetVariableIdentifier()))
     {   //Add undefined variable exception
         ExceptionList.Add(new UndefinedVariable(expression.GetVariableIdentifier()));
     }
 }
예제 #4
0
        void ButtonSubmitVariableClick(object sender, EventArgs e)
        {
            String        variable = textBoxVariable.Text;
            VarExpression ve       = new VarExpression(variable);

            expression = ve;
            finished();
        }
예제 #5
0
        public override Expression Visit(VarExpression expression)
        {
            foreach (var def in expression.Declarations)
            {
                _scope.Define(def.Name, false);
            }

            return(base.Visit(expression));
        }
예제 #6
0
        public void ParseVarExpressionTest()
        {
            //Create parser and parse tokens
            ExpressionParser expressionParser = new ExpressionParser(Init("home"));
            VarExpression    expression       = expressionParser.ParseVarExpression();

            //Test variable identifier
            Assert.AreEqual("home", expression.GetVariableIdentifier());
        }
예제 #7
0
        /// <summary>
        /// Parse an VariableExpression
        /// </summary>
        /// <returns>Parsed VariableExpression</returns>
        public VarExpression ParseVarExpression()
        {
            VarExpression varExpression = new VarExpression();

            CurrentToken = TokenStream.NextToken();
            varExpression.SetVariableIdentifier(CurrentToken.GetValue().ToString());

            return(varExpression);
        }
예제 #8
0
        public virtual T Visit(VarExpression expression)
        {
            foreach (var decl in expression.Declarations.Where(d => d.Initializer != null))
            {
                decl.Initializer.Accept(this);
            }

            return(default(T));
        }
예제 #9
0
        /// <summary>
        /// Helper method for creating a deref instruction on a given object, typically used for
        /// validating the null-state of an object prior to calling a member method of it.
        /// </summary>
        /// <param name="objectToDereference">Variable corresponding to the object to
        /// dereference.</param>
        /// <param name="type">The type of the object being dereferenced.</param>
        /// <param name="state">The program state for the SIL instruction.</param>
        /// <returns>SIL instruction representing the dereference.</returns>
        protected static Load CreateDereference(VarExpression objectToDereference,
                                                Typ type,
                                                ProgramState state)
        {
            var noId = state.GetIdentifier(Identifier.IdentKind.None);

            return(new Load(identifierAssignedTo: noId,
                            lvalue: objectToDereference,
                            type: type.StripPointer(),
                            location: state.CurrentLocation));
        }
예제 #10
0
 private string GenerateExpr(Expression e)
 {
     return(e switch
     {
         BinOp binop => GenerateBinExpr(binop),
         UnOp unop => GenerateUnExpr(unop),
         ConstExpression constExpression => GenerateConstExpr(constExpression),
         VarExpression varExpression => GenerateVarExpr(varExpression),
         CallExpression callExpression => GenerateCallExpression(callExpression),
         ConditionalExpression conditionalExpression => GenerateConditionalExpression(conditionalExpression),
         _ => throw new CompilerException(e.GetType().ToString(), e.Row, e.Column)
     });
예제 #11
0
        public void interpreterTest()
        {
            VarExpression varExpression = new VarExpression(0);
            List <string> list          = new List <string>();

            list.Add("1");
            list.Add("+");
            list.Add("3");
            list.Add("-");
            list.Add("1");
            int i = varExpression.interpreter(list);

            Assert.AreEqual(1, i);
        }
예제 #12
0
        /// <summary>
        /// Creates a <see cref="CfgNode"/> containing instructions for memory allocation as well
        /// as constructor invocation.
        /// </summary>
        /// <param name="type">The SIL type to be allocate memory for.</param>
        /// <param name="state">Current program state.</param>
        /// <returns>Node with the object allocation instructions, as well as the variable which
        /// represents the new object.</returns>
        protected static (CfgNode, VarExpression) CreateObjectAllocationNode(Tptr type,
                                                                             ProgramState state)
        {
            var typeName = type.StripPointer().ToString();

            var newObjectIdentifier = state.GetIdentifier(Identifier.IdentKind.Normal);
            var newObjectVariable   = new VarExpression(newObjectIdentifier);
            var callFlags           = new Call.CallFlags(isVirtual: false,
                                                         noReturn: false,
                                                         isObjCBlock: false);
            var objectAllocationCall =
                new Call(newObjectIdentifier,
                         type,
                         new ConstExpression(ProcedureName.BuiltIn__new),
                         new List <Call.CallArg>
            {
                new Call.CallArg(
                    new SizeofExpression(
                        type.StripPointer(),
                        SizeofExpression.SizeofExpressionKind.exact),
                    type)
            },
                         callFlags,
                         state.CurrentLocation);

            var objectConstructorCall =
                new Call(state.GetIdentifier(Identifier.IdentKind.Normal),
                         new Tvoid(),
                         new ConstExpression(new ProcedureName(".ctor",
                                                               new List <string>(),
                                                               typeName,
                                                               "System.Void",
                                                               false)),
                         new List <Call.CallArg>
            {
                new Call.CallArg(newObjectVariable, type)
            },
                         callFlags,
                         state.CurrentLocation);

            var node = new StatementNode(state.CurrentLocation,
                                         StatementNode.StatementNodeKind.Call,
                                         state.ProcDesc,
                                         comment: $"System.Void {typeName}::.ctor()");

            node.Instructions.Add(objectAllocationCall);
            node.Instructions.Add(objectConstructorCall);

            return(node, newObjectVariable);
        }
예제 #13
0
        public virtual Expression Visit(VarExpression expression)
        {
            var declarations = expression.Declarations.Select(d =>
            {
                if (d.Initializer == null)
                {
                    return(new VarExpression.Declaration(d.Name, null));
                }

                return(new VarExpression.Declaration(d.Name, d.Initializer.Accept(this)));
            }).ToList();

            return(new VarExpression(expression.Token, declarations, expression.IsReadOnly)
            {
                EndToken = expression.EndToken
            });
        }
예제 #14
0
        private void InitializeStruct(VarExpression fieldParentVariable,
                                      TypeDefinition parentTypeDefinition,
                                      List <SilInstruction> structFieldInitializationInstructions,
                                      ProgramState state,
                                      HashSet <TypeDefinition> parentTypeDefinitions)
        {
            foreach (var fieldReference in parentTypeDefinition.Fields)
            {
                var fieldExpression = CreateFieldExpression(fieldParentVariable, fieldReference);

                var defaultValue = GetDefaultValue(fieldReference.FieldType);

                // Struct field; the default value must be recursively filled.
                if (fieldReference.FieldType is TypeDefinition fieldTypeDefinition &&
                    fieldTypeDefinition.BaseType != null &&
                    fieldTypeDefinition.BaseType.FullName == "System.ValueType")
                {
                    if (parentTypeDefinitions.Contains(fieldTypeDefinition))
                    {
                        throw new Exception("Unable to handle cyclical struct type " +
                                            $"{fieldTypeDefinition.FullName}");
                    }

                    // Allocates the struct field and stores it into the parent.
                    (var structFieldMemoryAllocationCall, var structFieldVariable) =
                        CreateMemoryAllocationCall(fieldTypeDefinition, state);
                    structFieldInitializationInstructions.Add(structFieldMemoryAllocationCall);
                    structFieldInitializationInstructions.Add(
                        new Store(fieldExpression,
                                  structFieldVariable,
                                  Typ.FromTypeReferenceNoPointer(fieldReference.DeclaringType),
                                  state.CurrentLocation));

                    // Add the field to the parent definitions before recursing; remove after
                    // recursive call returns.
                    parentTypeDefinitions.Add(fieldTypeDefinition);
                    // Recursively initializes the struct field.
                    InitializeStruct(structFieldVariable,
                                     fieldTypeDefinition,
                                     structFieldInitializationInstructions,
                                     state,
                                     parentTypeDefinitions);
                    parentTypeDefinitions.Remove(fieldTypeDefinition);
                }
예제 #15
0
        public void ParseCatExpressionTest()
        {
            //Create parser and parse tokens
            ExpressionParser expressionParser = new ExpressionParser(Init("expression+'symbol"));
            Expression       expression       = expressionParser.ParseExpression();

            //Check type of expression
            Assert.AreEqual(typeof(CatExpression), expression.GetType());
            CatExpression parsedCatExpression = (CatExpression)expression;

            //Check expressions in catexpression
            Assert.AreEqual(typeof(VarExpression), parsedCatExpression.GetLeftExpression().GetType());
            Assert.AreEqual(typeof(SymExpression), parsedCatExpression.GetRightExpression().GetType());

            VarExpression left  = (VarExpression)parsedCatExpression.GetLeftExpression();
            SymExpression right = (SymExpression)parsedCatExpression.GetRightExpression();

            Assert.AreEqual("expression", left.GetVariableIdentifier());
            Assert.AreEqual("symbol", right.GetSym());
        }
예제 #16
0
        protected override bool ParseCilInstructionInternal(Instruction instruction,
                                                            ProgramState state)
        {
            switch (instruction.OpCode.Code)
            {
            case Code.Box:
                (var value, var type) = state.Pop();

                var boxedValueIdentifier = state.GetIdentifier(Identifier.IdentKind.Normal);
                var boxedObjectVariable  = new VarExpression(boxedValueIdentifier);
                var boxedObjectType      = new BoxedValueType(Tptr.PtrKind.Pk_pointer,
                                                              new Tstruct("System.Object"),
                                                              value,
                                                              type);
                var callFlags = new Call.CallFlags(false, false, false);

                // The value in question is boxed into a generic object.
                var objectAllocationCall =
                    new Call(boxedValueIdentifier,
                             boxedObjectType,
                             new ConstExpression(ProcedureName.BuiltIn__new),
                             new List <Call.CallArg>
                {
                    new Call.CallArg(
                        new SizeofExpression(
                            boxedObjectType.StripPointer(), "exact"),
                        boxedObjectType)
                },
                             callFlags,
                             state.CurrentLocation);

                var objectConstructorCall =
                    new Call(state.GetIdentifier(Identifier.IdentKind.Normal),
                             new Tvoid(),
                             new ConstExpression(new ProcedureName(".ctor",
                                                                   new List <string>(),
                                                                   "System.Object",
                                                                   "System.Void",
                                                                   false)),
                             new List <Call.CallArg>
                {
                    new Call.CallArg(boxedObjectVariable, boxedObjectType)
                },
                             callFlags,
                             state.CurrentLocation);

                var node = new StatementNode(state.CurrentLocation,
                                             StatementNode.StatementNodeKind.Call,
                                             state.ProcDesc,
                                             comment: "System.Void System.Object::.ctor()");
                node.Instructions.Add(objectAllocationCall);
                node.Instructions.Add(objectConstructorCall);
                RegisterNode(state, node);

                state.PushExpr(boxedObjectVariable, boxedObjectType);
                state.PushInstruction(instruction.Next, node);
                state.AppendToPreviousNode = true;

                return(true);

            default:
                return(false);
            }
        }
예제 #17
0
        protected static (CfgNode, CfgNode) CreateExceptionTypeCheckBranchNodes(
            ProgramState state, ExceptionHandler handler, Identifier exceptionIdentifier)
        {
            var handlerStartLocation = GetHandlerStartLocation(state, handler);
            var exceptionExpression  = new VarExpression(exceptionIdentifier);
            var isInstIdentifier     = state.GetIdentifier(Identifier.IdentKind.Normal);
            var isInstArgs           = new List <Call.CallArg>
            {
                new Call.CallArg(exceptionExpression,
                                 Typ.FromTypeReference(handler.CatchType)),
                new Call.CallArg(
                    new SizeofExpression(
                        Typ.FromTypeReferenceNoPointer(handler.CatchType),
                        SizeofExpression.SizeofExpressionKind.exact),
                    new Tvoid())
            };
            // We don't mark the function output as an isinst output, as there is no load or store
            // of it.
            var isInstCall = new Call(isInstIdentifier,
                                      new Tint(Tint.IntKind.IBool),
                                      new ConstExpression(ProcedureName.BuiltIn__instanceof),
                                      isInstArgs,
                                      new Call.CallFlags(),
                                      handlerStartLocation);

            var isInstOutputExpression = new VarExpression(isInstIdentifier);
            var pruneTrueInstruction   = new Prune(isInstOutputExpression,
                                                   true,
                                                   Prune.IfKind.Ik_switch,
                                                   handlerStartLocation);

            var pruneFalseInstruction = new Prune(new UnopExpression(UnopExpression.UnopKind.LNot,
                                                                     isInstOutputExpression,
                                                                     null),
                                                  false,
                                                  Prune.IfKind.Ik_switch,
                                                  handlerStartLocation);

            var setCatchVarInstruction = new Store(GetHandlerCatchVar(state, handler),
                                                   exceptionExpression,
                                                   Typ.FromTypeReference(state.Method.ReturnType),
                                                   handlerStartLocation);

            var pruneTrueNode = new PruneNode(handlerStartLocation,
                                              true,
                                              PruneNode.PruneNodeKind.ExceptionHandler,
                                              Prune.IfKind.Ik_switch,
                                              state.ProcDesc);

            var pruneFalseNode = new PruneNode(handlerStartLocation,
                                               false,
                                               PruneNode.PruneNodeKind.ExceptionHandler,
                                               Prune.IfKind.Ik_switch,
                                               state.ProcDesc);


            pruneTrueNode.Instructions.AddRange(new List <SilInstruction>
            {
                isInstCall, pruneTrueInstruction, setCatchVarInstruction
            });

            pruneFalseNode.Instructions.AddRange(new List <SilInstruction>
            {
                isInstCall, pruneFalseInstruction
            });
            pruneTrueNode.BlockEndOffset = state.MethodExceptionHandlers
                                           .GetBlockEndOffsetFromOffset(
                state.CurrentInstruction.Offset);
            pruneFalseNode.BlockEndOffset = state.MethodExceptionHandlers
                                            .GetBlockEndOffsetFromOffset(
                state.CurrentInstruction.Offset);
            state.Cfg.RegisterNode(pruneTrueNode);
            state.Cfg.RegisterNode(pruneFalseNode);
            return(pruneTrueNode, pruneFalseNode);
        }
예제 #18
0
 private string GenerateVarExpr(VarExpression e)
 {
     return($"mov eax, dword ptr[ebp{GetVarOffset(e.varName)}] ; {e.varName}\n" +
            $"push eax\n");
 }
예제 #19
0
        public void VarExpressionTest_1()
        {
            VarExpression varExpression_1 = new VarExpression(-1);

            Assert.IsNotNull(varExpression_1);
        }
예제 #20
0
        protected override bool ParseCilInstructionInternal(Instruction instruction,
                                                            ProgramState state)
        {
            var field = instruction.Operand as FieldReference;
            // An object expression for an instance field and a class expression for a static
            // field.
            Expression fieldOwnerExpression;
            Typ        fieldType;

            switch (instruction.OpCode.Code)
            {
            case Code.Ldfld:
            case Code.Ldflda:
                (var objectExpression, var objectExpressionType) = state.Pop();
                // Handles the case in which the address of the owning object is on the stack.
                if (objectExpressionType is Address address)
                {
                    // The value at the address is the parent expression, matching how the
                    // field is initialized.
                    var addressValueIdentifier = state.GetIdentifier(
                        Identifier.IdentKind.Normal);
                    state.PreviousNode.Instructions.Add(
                        new Load(addressValueIdentifier,
                                 address.Value,
                                 Typ.FromTypeReferenceNoPointer(field.DeclaringType),
                                 state.CurrentLocation));
                    fieldOwnerExpression = new VarExpression(addressValueIdentifier);
                }
                // The expression represents the object itself.
                else
                {
                    fieldOwnerExpression = objectExpression;
                }
                break;

            case Code.Ldsfld:
            case Code.Ldsflda:
                fieldOwnerExpression = new LvarExpression(
                    new GlobalVariable(field.DeclaringType.GetCompatibleFullName()));
                break;

            default:
                return(false);
            }
            // An identifier to store the field expression.
            var fieldIdentifier = state.GetIdentifier(Identifier.IdentKind.Normal);

            fieldType = Typ.FromTypeReferenceNoPointer(field.FieldType);
            var fieldExpression = CreateFieldExpression(fieldOwnerExpression, field);

            if (instruction.OpCode.Code == Code.Ldfld || instruction.OpCode.Code == Code.Ldsfld)
            {
                state.PreviousNode.Instructions.Add(new Load(fieldIdentifier,
                                                             fieldExpression,
                                                             Typ.FromTypeReferenceNoPointer(
                                                                 field.DeclaringType),
                                                             state.CurrentLocation));
                state.AppendToPreviousNode = true;
                state.PushExpr(new VarExpression(fieldIdentifier), fieldType);
            }
            // Instruction is either Ldflda or Ldsflda.
            else
            {
                var fieldAddressVariableType =
                    new Address(Tptr.PtrKind.Pk_pointer,
                                Typ.FromTypeReferenceNoPointer(
                                    field.FieldType),
                                fieldExpression,
                                referenceKind: Address.ReferenceKind.Field);
                state.PushExpr(fieldExpression, fieldAddressVariableType);
            }
            state.PushInstruction(instruction.Next);
            return(true);
        }
예제 #21
0
 public virtual void Visit(VarExpression expression)
 {
     VisitSubNodes(expression);
 }