/// <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; }
/// <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; }
/// <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; }
public RefVariable(Id id, CSim.Core.Type t, Machine m) : base(id, t, m) { this.SetType( m.TypeSystem.GetRefType( t ) ); this.pointedVble = null; }
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 ); }
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; }
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; }
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 ] ); } }
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 ); }
/// <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; }