Esempio n. 1
0
Ilwis::OperationImplementation::State Coord2Pixel::prepare(ExecutionContext *ctx, const SymbolTable& symTable)
{
    QString raster = _expression.parm(0).value();
    if (!_inputGC.prepare(raster)) {
        ERROR2(ERR_COULD_NOT_LOAD_2,raster,"");
        return sPREPAREFAILED;
    }
    if ( _expression.parameterCount() == 2) {
        QString name = _expression.parm(1).value();
        QVariant var = symTable.getValue(name);
        _coord = var.value<Coordinate>();
    }
    if ( _expression.parameterCount() == 3) {
        bool ok1, ok2, ok3=true;
        double x = _expression.parm(1).value().toDouble(&ok1);
        double y = _expression.parm(2).value().toDouble(&ok2);
        double z = 0;
        if(_expression.parameterCount() == 4) {
            z  = _expression.parm(2).value().toDouble(&ok3);
        }
        if (! (ok1 && ok2 && ok3)) {
            ERROR2(ERR_ILLEGAL_VALUE_2,"Coordinate", QString("%1 %2 %3").arg(x,y,x));
            return sPREPAREFAILED;
        }
        _coord = Coordinate(x,y,z)    ;
    }
    if ( _expression.parameterCount(false) == 1) {
        _outName = _expression.parm(0,true,false).value();
    }
    if ( _coord.isValid())
        return sPREPARED;

    return sPREPAREFAILED;
}
Esempio n. 2
0
bool TermNode::doIDStatement(SymbolTable &symbols, int scope, ExecutionContext *ctx) {
    QString expression;
    if ( ctx->_additionalInfo.find(IMPLICITPARMATER0) != ctx->_additionalInfo.end()){
        _value = { _id->id(), NodeValue::ctID};
        return true;

    }

    _id->evaluate(symbols, scope, ctx);
    QString value;

    if ( _id->isReference()) {
        if ( symbols.getSymbol(_id->id(),scope).isValid())
            value = _id->id();
        else
            return false;
    }
    else
        value = _id->id();
    if ( _selectors.size() > 0) {
        // selectors are handled by successive calls to the selection operation and in the end giving the temp object to the value
        expression = buildBracketSelection(value);
        if(!Ilwis::commandhandler()->execute(expression, ctx, symbols)) {
            throw ScriptExecutionError(TR("Expression execution error in script; script aborted. See log for further details"));
        }
        QString outgc = ctx->_results[0];
        value = outgc;
    }


    _value = {value, NodeValue::ctID};
    return value != "" && value != sUNDEF;
}
Esempio n. 3
0
bool TermNode::doMethodStatement(SymbolTable &symbols, int scope, ExecutionContext *ctx){
    QString parms = "(";
    for(int i=0; i < ctx->_additionalInfo.size() && ctx->_useAdditionalParameters; ++i){
        QString extrapar = IMPLICITPARMATER + QString::number(i);
        auto iter = ctx->_additionalInfo.find(extrapar);
        if ( iter != ctx->_additionalInfo.end()){
            if ( parms.size() > 1)
                parms += ",";
            parms += (*iter).second;
        }
    }
    for(int i=0; i < _parameters->noOfChilderen(); ++i) {
        bool ok = _parameters->child(i)->evaluate(symbols, scope, ctx);

        if (!ok)
            return false;
        QString name = getName(_parameters->child(i)->value());
        if ( parms.size() > 1)
            parms += ",";
        parms += name;

    }
    parms += ")";
    QString expression = _id->id() + parms;
    bool ok = Ilwis::commandhandler()->execute(expression, ctx, symbols);
    if ( !ok || ctx->_results.size() != 1)
        throw ScriptExecutionError(TR("Expression execution error in script; script aborted. See log for further details"));

    _value = {symbols.getValue(ctx->_results[0]), ctx->_results[0], NodeValue::ctMethod};
    return true;
}
Esempio n. 4
0
Function* FunctionAST::Codegen()
{
  Function* theFunction = Proto->Codegen();
  if(theFunction == 0)
    return 0;

  BasicBlock* BB = BasicBlock::Create(getGlobalContext(),"entry",theFunction);
  Builder.SetInsertPoint(BB);

  Proto->CreateArgumentAllocas(theFunction);

  vector<ExprAST*>::iterator it = Body.begin();
  Value* last;
  for(it = Body.begin(); it != Body.end(); ++it)
  {
    last = (*it)->Codegen();
    if (!last)
      break;
  }
  
  if(last)
  {
    Builder.CreateRet(last);
    verifyFunction(*theFunction);
    NamedValues.clear();
    return theFunction;
  }
  //If it gets here there's an error! erase the function
  theFunction->eraseFromParent();
  return 0;
}
bool HashMap::get( const std::string& key, std::string& value) const
{
	uint32_t id = m_symtab.get( key);
	if (!id) return false;
	value.append( m_value_strings.c_str() + m_value_refs[ id-1]);
	return true;
}
ExprResult IdentifierNode::eval()
{
	ExprResult result;
	ActivationReg* areg = ActivationReg::getInstance();
	SymbolTable* table = areg->top();
	Symbol* sym = table->get(mName);
	if (sym != NULL && sym->isVar())
	{
		result.setType(sym->getType());
		result.setValue(sym->getValue());
	}
	else
	{
		Log::fatal("Uso de identificador não definido");
	}
	return result;
}
Esempio n. 7
0
void NameSpace::extract(Symbol::Kind kind, SymbolTable& table) const
{
    for (SymbolTable::const_iterator it = _symbols.begin(); it != _symbols.end(); ++it)
    {
        if (it->second->kind() == kind)
            table.insert(*it);
    }
}
static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyModule(ExecState* state)
{
    VM& vm = state->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSValue val = state->argument(0);

    // If the given bytes argument is not a BufferSource, a TypeError exception is thrown.
    JSArrayBuffer* arrayBuffer = val.getObject() ? jsDynamicCast<JSArrayBuffer*>(val.getObject()) : nullptr;
    JSArrayBufferView* arrayBufferView = val.getObject() ? jsDynamicCast<JSArrayBufferView*>(val.getObject()) : nullptr;
    if (!(arrayBuffer || arrayBufferView))
        return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val))));

    if (arrayBufferView ? arrayBufferView->isNeutered() : arrayBuffer->impl()->isNeutered())
        return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("underlying TypedArray has been detatched from the ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val))));

    size_t byteOffset = arrayBufferView ? arrayBufferView->byteOffset() : 0;
    size_t byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength();
    const auto* base = arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data());

    Wasm::Plan plan(&vm, base + byteOffset, byteSize);
    // On failure, a new WebAssembly.CompileError is thrown.
    plan.run();
    if (plan.failed())
        return JSValue::encode(throwException(state, scope, createWebAssemblyCompileError(state, plan.errorMessage())));

    // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module.
    auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), asInternalFunction(state->jsCallee())->globalObject()->WebAssemblyModuleStructure());
    RETURN_IF_EXCEPTION(scope, { });

    // The export symbol table is the same for all Instances of a Module.
    SymbolTable* exportSymbolTable = SymbolTable::create(vm);
    for (auto& exp : plan.exports()) {
        auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary);
        exportSymbolTable->set(NoLockingNecessary, exp.field.impl(), SymbolTableEntry(VarOffset(offset)));
    }

    // Only wasm-internal functions have a callee, stubs to JS do not.
    unsigned calleeCount = plan.internalFunctionCount();
    JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.takeModuleInformation(), plan.takeCallLinkInfos(), plan.takeWasmToJSStubs(), plan.takeFunctionIndexSpace(), exportSymbolTable, calleeCount);
    plan.initializeCallees(state->jsCallee()->globalObject(), 
        [&] (unsigned calleeIndex, JSWebAssemblyCallee* jsEntrypointCallee, JSWebAssemblyCallee* wasmEntrypointCallee) {
            result->setJSEntrypointCallee(vm, calleeIndex, jsEntrypointCallee);
            result->setWasmEntrypointCallee(vm, calleeIndex, wasmEntrypointCallee);
        });
    return JSValue::encode(result);
}
Esempio n. 9
0
void
ASTTerm1_Root::dump()
{
  if (univ == -1)
    cout << "Root";
  else
    cout << "Root(" << symbolTable.lookupSymbol(univ) << ")";
}
Esempio n. 10
0
int main( int /* argc */, char** /* argv */ )
{
	Scanner scanner = Scanner();
	
	SymbolTable st = SymbolTable();
	
	Token *currTok;
	currTok = scanner.nextToken();
	
	while( 1 )
	{					
		std::cout << currTok->tokenCodeToString();
		
		if( currTok->getDataType() == dt_OP )
			std::cout << "(" << currTok->opCodeToString() << ")";
		else if( currTok->getDataType() != dt_KEYWORD && currTok->getDataType() != dt_NONE )
		{
			std::cout << "(" << currTok->getDataValue().lexeme << ")";
		}	
		std::cout << " ";
		
		
		//symtab
		if( currTok->getTokenCode() == tc_ID || currTok->getTokenCode() == tc_NUMBER )
		{
			SymbolTableEntry *entry = st.lookup( currTok->getDataValue().lexeme );
			
			if(!entry)
			{
				entry = st.insert( currTok->getDataValue().lexeme );
				currTok->setSymTabEntry( entry );
			}
			currTok->setSymTabEntry( entry );	
		}
		
		
		if(currTok->getTokenCode() == tc_EOF)
			break;
		currTok = scanner.nextToken();
	}
	
	std::cout << "\n\n";
	st.print();
	return 0;
}
Esempio n. 11
0
void VarDefinition(SymbolTable &table)
{
    if (symbol!=IDEN) ErrorHandler("Error defination shold begin with iden");//Throw Error while define var, expect iden
    table.Push(token,  varsk);
    do {
        GetNextSym();
        if (symbol==COLON) break;
        if (symbol!=COMMA) ErrorHandler("multi-var should be seperate via ,");
        GetNextSym();
        if (symbol!=IDEN) ErrorHandler("Error defination should be iden, but you used "+token); //throw error while define var
        table.Push(token,  varsk);
    } while (true);
    GetNextSym();
    if (symbol==INTTK) table.SetType( integerst);
    else if (symbol==CHARTK) table.SetType( charst);
    //table.SetKind(varsk);
    else if (symbol==ARRAYTK) {
        GetNextSym();
        if (symbol!=LBRACK) ErrorHandler("Error while define arr,miss [");//Throw Error expect [
        GetNextSym();
        if (symbol!=INTCON) ErrorHandler("[k] k should be number");// Throw Error expect number
        table.SetTypeValue( arrOfCh, number);
        GetNextSym();
        if (symbol!=RBRACK) ErrorHandler("define arr, miss ]");//Throw Error expect ]
        GetNextSym();
        if (symbol!=OFTK) ErrorHandler("define arr miss of");//Throw Error expect of
        GetNextSym();
        if (symbol!=INTTK && symbol!=CHARTK) ErrorHandler("define arr miss char or integer"); //Throw error expect char or integer
        if (symbol==INTTK) table.SetType( arrOfInt);
    } else ErrorHandler("var type illegal");
    table.FillBack();
    GetNextSym();
    if (symbol==IDEN) ErrorHandler("miss ;");
}
Esempio n. 12
0
void 
IdentList::dump()
{
  for (iterator i = begin(); i != end();) {
    cout << symbolTable.lookupSymbol(*i);
    if (++i != end())
      cout << ",";
  }
}
Esempio n. 13
0
Symbol* 
SymbolTable::findInAll(SymbolTable* gamma, std::string key) 
{
    assert(gamma && "No gamma!");
    SymbolTable* current = gamma;
    List<SymbolTable*>* blocks = current->getBlocks();

    for (int i = 0; i < blocks->getNumElements(); i++) 
    {
        SymbolTable* tmpST = blocks->getNth(i);
        Symbol* sym = tmpST->findLocal(key);
        if (sym != NULL) 
        {
            return sym;
        }
    }
    return NULL;
}
	OolongVisitor(TableVisitor *tv) {
		tableVisitor = new TableVisitor(*tv);
		symbolTable = tv->symbolTable;
		arreglo_de_variables = new vector<Simbolo>(symbolTable->getOrderedTable());
		//cout<<"CREADO EL OOLONG VISITOR\ntamanio = "<<endl<<tableVisitor->symbolTable->tamanio()<<endl;
		inAssignation = false;
		inMainFunction = true;
		output.open("prueba.j");
	}
Esempio n. 15
0
//-------------------------------------------------------------------------
//Function procedure_statement_2 implements the rule
//procedure_statement_2: procedure_statement -> ID ( expression_list )
//-------------------------------------------------------------------------
Exp* procedure_statement(string* id, List<Exp*>* EL)
{  Sym* S=ST.Find(*id);
   if (!S) yyerror("Semantic error - ID cannot be found");
   if (S->IsProcedureSymbol())
       return UserSubprogram((SubprogramSymbol*)S,EL);
   else if (S->IsStandardProcedureSymbol() ) 
       return StandardProcedure((StandardProcedureSymbol*)S,EL);
   else yyerror("Semantic error - ID must be a procedure");
}
Esempio n. 16
0
void traverseFullDepTree2()
{

	// assign a class index to all classes
	if (!parseFailed && !compileErrors) {
		buildClassTree();
		gNumClasses = 0;

		// now I index them during pass one
		indexClassTree(class_object, 0);
		setSelectorFlags();
		if (2*numClassDeps != gNumClasses) {
			error("There is a discrepancy.\n");
                    /* not always correct
                    if(2*numClassDeps < gNumClasses) {
                        post("Duplicate files may exist in the directory structure.\n");
                    } else {
                        post("Some class files may be missing.\n");
                    }
                    */
                    post("numClassDeps %d   gNumClasses %d\n", numClassDeps, gNumClasses);
			findDiscrepancy();
			compileErrors++;
		} else {
			double elapsed;
			buildBigMethodMatrix();
			SymbolTable* symbolTable = gMainVMGlobals->symbolTable;
			post("\tNumber of Symbols %d\n", symbolTable->NumItems());
			post("\tByte Code Size %d\n", totalByteCodes);
			//elapsed = TickCount() - compileStartTime;
			//elapsed = 0;
                        elapsed = elapsedTime() - compileStartTime;
                        post("\tcompiled %d files in %.2f seconds\n",
				gNumCompiledFiles, elapsed );
			if(numOverwrites == 1){
				post("\nInfo: One method is currently overwritten by an extension. To see which, execute:\nMethodOverride.printAll\n\n");
			}
			else if(numOverwrites > 1){
				post("\nInfo: %i methods are currently overwritten by extensions. To see which, execute:\nMethodOverride.printAll\n\n", numOverwrites);
			}
			post("compile done\n");
		}
	}
}
Esempio n. 17
0
void log_variable( string variable_name, SymbolTable& table, bool status_key )
{
	if( status_key )
	{
		if( table.exist_symbol( variable_name ) )
		{
			Symbol variable = table.find_symbol_by_name( variable_name );
			variable.list_attributes_symbol();

		} else
		{
			print_message_undeclared_variable( );
		}

	} else
	{
		// Nothing To Do
	}
}
Esempio n. 18
0
//-------------------------------------------------------------------------
//Function statement implements the rule
//statement -> variable := expression
//-------------------------------------------------------------------------
List<Exp*>* statement(Exp* variable,Exp* expression)
{   if (variable->Type()!=expression->Type()) yyerror("Semantic error:Assignment type mismatch");
    string tc=expression->Type()->TypeChar();
    PCode* P=new PCode("","sti",tc,"");
    Exp* E=new Exp(variable,expression,ST.TVoid(),P);
    E->Print(tfs);
    List<Exp*>* S=new List<Exp*>;
    S->Insert(E);
    return S;
}
Esempio n. 19
0
void JSScope::collectClosureVariablesUnderTDZ(JSScope* scope, VariableEnvironment& result)
{
    for (; scope; scope = scope->next()) {
        if (!scope->isLexicalScope() && !scope->isCatchScope())
            continue;

        if (scope->isModuleScope()) {
            AbstractModuleRecord* moduleRecord = jsCast<JSModuleEnvironment*>(scope)->moduleRecord();
            for (const auto& pair : moduleRecord->importEntries())
                result.add(pair.key);
        }

        SymbolTable* symbolTable = jsCast<JSSymbolTableObject*>(scope)->symbolTable();
        ASSERT(symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope || symbolTable->scopeType() == SymbolTable::ScopeType::CatchScope);
        ConcurrentJSLocker locker(symbolTable->m_lock);
        for (auto end = symbolTable->end(locker), iter = symbolTable->begin(locker); iter != end; ++iter)
            result.add(iter->key);
    }
}
Esempio n. 20
0
SymbolTable *
SymbolTable::addWithScope(std::string key, TType* ttype, int scope) 
{
    SymbolTable *newGamma = new SymbolTable;
    Symbol *sym;
    newGamma->setParent(this);

    if (_this) 
    {
        newGamma->setThis(_this);
    }

    sym = new Symbol(key, ttype, scope, newGamma);
    assert(sym && "No symbol to enter to ST");
    _table->enter(key, sym, false);
    _blocks->append(newGamma);

    return newGamma;
}
Esempio n. 21
0
Symbol *
SymbolTable::findSuper(std::string key) 
{
    SymbolTable *current = _super;

    if (!_super) 
    {
        return NULL;
    }

    for ( ; current != NULL; current = current->getSuper()) 
    {
        if (Symbol* sym = current->findLocal(key)) 
        {
            return sym;
        }
    }
    return NULL;
}
Esempio n. 22
0
/* return true if the symbol has a name crash with another symbol in
 * its parent (a symbol table).
 * This implementation just consider name crashes and ignore the symbol
 * type.
 */
static bool is_var_name_crashd_locally(const Symbol* symbol)
{
  LString sname = symbol->get_name();
  if (sname == emptyLString) return false;
  SymbolTable* symtab = to<SymbolTable>(symbol->get_parent());
  if (!is_kind_of<VariableSymbol>(symbol)) return false;
  for (Iter<SymbolTableObject*> iter = 
	 symtab->get_symbol_table_object_iterator();
       iter.is_valid();
       iter.next()) {
    if (symbol == const_cast<const SymbolTableObject*>(iter.current()))
      continue;
    if (!is_kind_of<VariableSymbol>(iter.current())) continue;
    if (iter.current()->get_name() == sname) {
      return true;
    }
  }
  return false;
}
Esempio n. 23
0
GuideFunc*
MonaUntypedAST::makeStateSpace(char *ssname, char *pos,
			       char **leftpos, char **rightpos,
			       SSKind kind)
{
  Name n = Name(ssname, dummyPos);
  symbolTable.insertStatespace(&n);
  
  *leftpos = new char[strlen(pos)+2];
  sprintf(*leftpos, "%s0", pos);
  *leftpos = symbolTable.insertString(*leftpos);
  *rightpos = new char[strlen(pos)+2];
  sprintf(*rightpos, "%s1", pos);
  *rightpos = symbolTable.insertString(*rightpos);
  
  GuideFunc *g = new GuideFunc(new Name(ssname, dummyPos), NULL, NULL, kind);
  guide_declaration->funcList->push_back(g);
  return g;
}
Esempio n. 24
0
char*
MonaUntypedAST::makeDummySS(char *univ)
{
  char *ssname = new char[strlen(univ)+7];
  sprintf(ssname, "dummy-%s", univ);
  ssname = symbolTable.insertString(ssname);

  if (!symbolTable.exists(ssname)) {
    Name n = Name(ssname, dummyPos);
    symbolTable.insertStatespace(&n);
    guide_declaration->funcList->push_back
      (new GuideFunc(new Name(ssname, dummyPos),
		     new Name(ssname, dummyPos),
		     new Name(ssname, dummyPos),
		     SS_DUMMY));
  }

  return ssname;
}
Esempio n. 25
0
void ExecutionContext::addOutput(SymbolTable &tbl, const QVariant &var, const QString &nme, quint64 tp, const Resource& resource)
{
    QString name =  nme == sUNDEF ? SymbolTable::newAnonym() : nme;
    tbl.addSymbol(name,_scope, tp, var);
    _results.clear();
    _results.push_back(name);
    if ( name.indexOf(ANONYMOUS_PREFIX) == -1 && resource.isValid()) {
        mastercatalog()->addItems({resource});
    }
}
Esempio n. 26
0
void TestAssembler()
{
	Compiler comp("Methods");

	{
		SymbolTable<Variable> args;
		args.Define(make_shared<Variable>("a", ATOMIC_TYPE::TYPE_INT));
		args.Define(make_shared<Variable>("b", ATOMIC_TYPE::TYPE_INT));
		auto fn = comp.NewFunction(DataType(ATOMIC_TYPE::TYPE_INT), "DoSum", args);

		fn->ldarg("a");
		fn->ldarg("b");
		fn->add();
		fn->ret();
	}

	{
		SymbolTable<Variable> args;
		args.Define(make_shared<Variable>("value", ATOMIC_TYPE::TYPE_INT));
		auto fn = comp.NewFunction(DataType(ATOMIC_TYPE::TYPE_VOID), "PrintSum", args);

		fn->ldstr("The Result is: ");
		fn->call(comp.GetFunction("PrintString"));
    
		fn->ldarg("value");
		fn->call(comp.GetFunction("PrintInt"));
    
		fn->ret();
	}

	{
		auto fn = comp.NewFunction(DataType(ATOMIC_TYPE::TYPE_VOID), "main", SymbolTable<Variable>());

		fn->ldc(10);
		fn->ldc(20);
		fn->call(comp.GetFunction("DoSum"));
		fn->call(comp.GetFunction("PrintSum"));
		fn->ret();
	}

	comp.Compile();
}
    //----------------------------------------------------------------------------
    void EvaluatorVisitor::visit( const AST::FragmentExpression* const node )
    {
        AST::INode* fragment = node->getFragment();

        // save state of symbol table
        SymbolTable scopeTable = mSymbolTable;

        AST::FragmentExpression::ParameterMap params = node->getParameterMap();
        AST::FragmentExpression::ParameterMap::iterator it;

        // temporary store params in symbol table

        for ( it = params.begin(); it != params.end(); ++it )
        {
            const String& paramName = it->first;
            AST::INode* node = it->second;

            scopeTable.setVariable( paramName, node );
        }

        // evaluate fragment
		if( fragment != 0 )
		{
			EvaluatorVisitor evaluator( scopeTable, mErrorHandler );
			fragment->accept( &evaluator );
			mBranchValue = evaluator.getValue();
		}
		else
		{
			std::ostringstream desc;
			desc << "Symbol " << node->getName() << " not declared!";
            if ( mErrorHandler )
            {
                Error err( Error::ERR_ITEM_NOT_FOUND, desc.str() );
                mErrorHandler->handleError( &err );
            }
		}


        // restore state of symbol table
        // mSymbolTable = saveTable;
    }
Esempio n. 28
0
void ProcDeClaration(SymbolTable &table)
{
    int backup = (int)ptable; // Backup, for updating the size of this table later
    ProcHeader(table);
    SubProgram(symbolTableList[ptable-1]);
    symbolTableList[backup].UpdateSize();
    //table.Top()->UpdateSize(symbolTableList[backup].GetSize());
    table.Top()->UpdateSize(4);
    if (symbol!=SEMICN) ErrorHandler("proc shold end with '"); //Error procedure should end with ;
    GetNextSym();
}
Esempio n. 29
0
void FuncDeClaration(SymbolTable &table)
{
    int backup = (int)ptable;
    FuncHeader(table);
    SubProgram(symbolTableList[ptable-1]);
    symbolTableList[backup].UpdateSize();
    //table.Top()->UpdateSize(symbolTableList[backup].GetSize());
    table.Top()->UpdateSize(4);
    if (symbol!=SEMICN) ErrorHandler("func declaration should end with ;");//Error function should end with ;
    GetNextSym();
}
Esempio n. 30
0
//--------------------------------------------------------------------
//expression: Parameterizes all relational expressions
//--------------------------------------------------------------------
Exp* expression(Exp* LE,Exp* RE,string relop)
{  Typ* LT=LE->Type();
   Typ* RT=RE->Type();
   Typ* B=ST.TBoolean();
   if (LT!=RT) yyerror("Semantic Error:unequal left and right types.");
   string typechar=LT->TypeChar();
   PCode* P=new PCode("",relop,typechar,"");
   Exp* E=new Exp(LE,RE,B,P);
   E->Print(tfs);
   return E;
}