示例#1
0
        /// <summary>
        /// Parses given input and executes its opcodes.
        /// </summary>
        /// <param name="input">The user's input, as a string.</param>
        /// <param name="machine">The machine in which to execute the input.</param>
        public static Variable[] Execute(Machine machine, string input)
        {
            var resultsDictionary = new Dictionary<string, Variable>();
            var parser = new Parser( input, machine );

            try {
                // Execute opcodes
                foreach(Opcode opcode in parser.Parse()) {
                    Variable result = opcode.Execute();
                    if ( result != null
                      && !( resultsDictionary.ContainsKey( result.Name.Value ) ) )
                    {
                        resultsDictionary.Add( result.Name.Value, result );
                    }
                }
            }
            finally {
                machine.TDS.Collect();
            }

            // Return the vector of results
            var toret = new Variable[ resultsDictionary.Count ];
            resultsDictionary.Values.CopyTo( toret, 0 );
            return toret;
        }
示例#2
0
文件: Opcode.cs 项目: Baltasarq/CSim
        /// <summary>
        /// Coerce the specified vble to type t, by creating another vble.
        /// </summary>
        /// <param name="t">The type to coerce the value, as Type.</param>
        /// <param name="vble">A Variable which is to be coerced.</param>
        /// <returns>>A new variable with coerced type, or the same variable.</returns>
        public static Variable Coerce(CSim.Core.Type t, Variable vble)
        {
            Variable toret = vble;
            Id id = new Id( "a" );

            id.SetIdWithoutChecks( "coerced_" + vble.Name.Name );

            if ( t != vble.Type ) {
                toret = new Variable( id, t, vble.Machine );
                toret.Address = vble.Address;
            }

            return toret;
        }
示例#3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CSim.Core.Function"/> class.
        /// Functions are defined by a return type, an indetifier, and a collection of
        /// formal parameters.
        /// </summary>
        /// <param name="id">The identifier of the function, as a string.</param>
        /// <param name="returnType">The return type, as a CSim.Core.Type.</param>
        /// <param name="formalParams">The formal parameters, as a vector.</param>
        protected Function(Machine m, string id, CSim.Core.Type returnType, Variable[] formalParams)
        {
            if ( id != null ) {
                id = id.Trim();
            }

            if ( string.IsNullOrEmpty( id ) ) {
                throw new ArgumentException( "void id in fn." );
            }

            if ( formalParams == null ) {
                formalParams = new Variable[]{};
            }

            this.machine = m;
            this.formalParams = formalParams;
            this.id = id;
            this.returnType = returnType;
        }
示例#4
0
 public RefVariable(Id id, CSim.Core.Type t, Machine m)
     : base(id, t, m)
 {
     this.SetType( m.TypeSystem.GetRefType( t ) );
     this.pointedVble = null;
 }
示例#5
0
        public override void Execute()
        {
            // Take value
            this.Value = this.Machine.ExecutionStack.Pop();

            // Take id
            this.Vble = this.Machine.TDS.SolveToVariable( this.Machine.ExecutionStack.Pop() );
            Variable rvalue = this.Machine.TDS.SolveToVariable( this.Value );

            if ( !( rvalue is TempVariable )
              && rvalue.Name.Name == this.Vble.Name.Name )
            {
                // The variable has just been created.
                this.Value = this.Machine.ExecutionStack.Pop();
            }

            // Prepare assign parts
            if ( this.Vble is TempVariable ) {
                throw new UnknownVbleException( "tmp vble: " + this.Vble.Name.Name );
            }

            Variable toret = this.Vble;

            // Chk types
            if ( !toret.Type.IsCompatibleWith( rvalue.Type ) ) {
                throw new TypeMismatchException(
                        rvalue.Name.Name + ": "
                        + rvalue.Type.ToString() + " != "
                        + toret.Type.ToString()
                    );
            }

            // Is lvalue a ref?
            var r = toret as RefVariable;

            if ( r != null ) {
                if ( !r.IsSet() ) {
                    this.SetRef( r, rvalue );
                    toret = r.PointedVble;
                } else {
                    toret = r.PointedVble;
                    toret.LiteralValue = rvalue.LiteralValue;
                }
            } else {
                if ( this.Value is StrLiteral ) {
                    string s = (string) rvalue.LiteralValue.Value;

                    Variable mblock = this.Machine.TDS.AddVector(
                        new Id( SymbolTable.GetNextMemoryBlockName() ),
                        this.Machine.TypeSystem.GetCharType(),
                        s.Length + 1
                    );

                    // Copy string contents
                    for(int i = 0; i < s.Length; ++i) {
                        this.Machine.Memory.Write( mblock.Address + i, new byte[]{ (byte) s[ i ] } );
                    }

                    // Set trailing zero
                    this.Machine.Memory.Write( mblock.Address + s.Length, new byte[]{ 0 } );

                    toret.LiteralValue = new IntLiteral( this.Machine, mblock.Address );
                } else {
                    toret.LiteralValue = rvalue.LiteralValue;
                }
            }

            this.Machine.ExecutionStack.Push( toret );
        }
示例#6
0
        private void SetRef(RefVariable lvalue, Variable rvalue)
        {
            // Check rvalue
            if ( rvalue is TempVariable ) {
                long address = rvalue.Address;

                rvalue = Machine.TDS.LookForAddress( rvalue.Address );

                if ( rvalue == null ) {
                    throw new UnknownVbleException( string.Format(
                                "[{0}]",
                        new IntLiteral( this.Machine, address ).ToPrettyNumber() ) );
                }

                if ( lvalue.AssociatedType != rvalue.GetTargetType() ) {
                    throw new TypeMismatchException( lvalue.Type.Name );
                }
            }

            var rvalueRef = rvalue as RefVariable;
            var rvaluePtr = rvalue as PtrVariable;

            // Assign to variable
            if ( rvalueRef != null ) {
                lvalue.PointedVble = rvalueRef.PointedVble;
            }
            else
            if ( rvaluePtr != null ) {
                lvalue.PointedVble = Machine.TDS.LookForAddress( rvaluePtr.IntValue );
            }
            else {
                lvalue.PointedVble = rvalue;
            }

            // Chk
            if ( lvalue.PointedVble.Address < 0 ) {
                throw new UnknownVbleException( rvalue.Name.Name );
            }

            if ( lvalue.PointedVble.Type != rvalue.Type ) {
                throw new TypeMismatchException(
                    lvalue.PointedVble.Type.ToString()
                    + " is not "
                    + rvalue.Type.ToString()
                );
            }

            return;
        }
示例#7
0
        public Variable Add(Variable v)
        {
            // Chk
            if ( this.IsIdOfExistingVariable( v.Name ) ) {
                throw new AlreadyExistingVbleException( v.Name.Name );
            }

            // Store
            v.Address = this.Reserve( v );
            this.tds.Add( v.Name.Name, v );

            return v;
        }
示例#8
0
        private void StoreAddressesToFill(Variable v, long[] addressesToFill = null)
        {
            // Create the vector of addresses, if needed
            if ( addressesToFill == null ) {
                addressesToFill = new long[ v.Type.Size ];
                for(int i = 0; i < addressesToFill.Length; ++i) {
                    addressesToFill[ i ] = v.Address + i;
                }
            }

            // Store the addresses to fill
            for (int i = 0; i < v.Type.Size; ++i) {
                this.addresses.Add( addressesToFill[ i ] );
            }
        }
示例#9
0
        internal void AddVariableInPlace(Variable v)
        {
            // Chk
            if ( this.IsIdOfExistingVariable( v.Name ) ) {
                throw new AlreadyExistingVbleException( v.Name.Name );
            }

            // Store
            this.tds.Add( v.Name.Name, v );
            this.StoreAddressesToFill( v );
        }
示例#10
0
        /// <summary>
        /// Reserve memory for the specified v.
        /// </summary>
        /// <param name='v'>
        /// The variable to reserve memory for.
        /// </param>
        public long Reserve(Variable v)
        {
            int tries = 100;
            Random randomEngine = new Random();
            int toret = -1;
            long[] addressesToFill = new long[ v.Type.Size ];

            while( toret < 0 ) {
                // Generate memory location
                do {
                    toret = randomEngine.Next( 0, this.Memory.Max - this.Machine.WordSize );

                    if ( ( toret + v.Type.Size ) >= this.Memory.Max ) {
                            toret = -1;
                    }
                } while( toret < 0 );

                // Create addresses to fill
                for (int i = 0; i < v.Type.Size; ++i) {
                    addressesToFill[ i ] = toret + i;
                }

                // Check against occupied addresses
                for (int i = 0; i < v.Type.Size; ++i) {
                    if ( this.addresses.Contains( addressesToFill[ i ] ) ) {
                        toret = -1;
                        break;
                    }
                }

                --tries;
                if ( tries < 0 ) {
                    break;
                }
            }

            // Re-check
            if ( toret < 0 ) {
                throw new ExhaustedMemoryException(
                    L18n.Get( L18n.Id.ErrReserving ) + ": " + v.Name );
            }

            this.StoreAddressesToFill( v, addressesToFill );
            return toret;
        }