예제 #1
0
파일: parser.c 프로젝트: markcheno/topaz
static Int32 Factor(void)
{
    Int32 type;
	
	switch(Token)
	{
	case tINTCONST:
		vm_genI(op_pushint,GetInt());
		NextToken();
        type=INT_TYPE;
		break;
	
	case tREALCONST:
		vm_genR(op_pushreal,GetReal());
		NextToken();
        type=REAL_TYPE;
		break;
		
	case tSTRINGCONST:
		vm_genS(op_pushstring,GetString());
		NextToken();
        type=STRING_TYPE;
		break;
		
	case tNOT:
        NextToken();
		type=Factor();
		vm_gen0(op_not);
		break;
		
	case tLPAREN:
		SkipToken(tLPAREN);
		type=Expr();
		SkipToken(tRPAREN);
		break;

	case tLBRACK:
		ArrayInitializer();
        type=ARRAY_TYPE;
		break;

	default:
		type=Rhs();
		break;
	}
    
    return type;
}
예제 #2
0
파일: pass1.cpp 프로젝트: huffman/CRUDASM7
void Pass1::accept_asgn(
	std::string asgn_nm, ParseNode *asgn_rhs, ParseNode *simple, std::string insn_name, Insn &insn,
	char asz, char osz
)
{
	/// fixme, do this!
	// 1. Get size of asgn_nm (destination of assignment).
	//    Actually, we can just look up asgn_nm in the symbol table.
	// 2. asgn_rhs is an 'rhs' node.
	//    If the rhs node is a NUM token then we have to give it a size that matches the destination
	//    size.
	// 3. Evaluation of 'rhs'.
	//    a. [?]
	
	std::map<std::string, Symbol *>::iterator symiter = symtab2.find(asgn_nm);
	if(symiter == symtab2.end())
	{
		throw ParseError("Destination of assignment not found in symbol table: " + asgn_nm,
			simple->lineNum,
			simple->fileNum,
			__LINE__
		);
	}
	Symbol &destsym = *symiter->second;
	Size &destsize = destsym.size;
	
	insn.stmts.push_back(Statement(SO_ASGN));
	Statement &stmt = insn.stmts.back();
	stmt.osz = osz;
	stmt.asz = asz;
	stmt.dest = &destsym;
	assert(stmt.dest->type == ST_LOCAL || stmt.dest->type == ST_EXTERN || stmt.dest->type == ST_ARGNAME);
	stmt.src.push_back(Rhs());
	Rhs &rhsT = stmt.src.back();
	
	accept_rhs(rhsT, asgn_rhs, insn_name, insn, destsize);
	
	if(rhsT.size.base != destsize.base || rhsT.size.scalar != destsize.scalar)
	{
///std::cout << rhsT.size.base << " " << rhsT.size.scalar << " " << destsize.base << " " << destsize.scalar << std::endl;
		throw ParseError("Size mismatch for assignment to " + asgn_nm,
			simple->lineNum,
			simple->fileNum,
			__LINE__
		);
	}
}
예제 #3
0
파일: pass1.cpp 프로젝트: huffman/CRUDASM7
void Pass1::accept_statement(ParseNode *stmt, std::string insn_name, Insn &insn)
{
	assert(stmt->token == RULE_STATEMENT);
	char osz = 0, asz = 0;
	std::list<ParseNode *>::iterator i = stmt->children.begin();
	assert(i != stmt->children.end());
	bool valid = true;
	while((*i)->token == RULE_PREFIX)
	{
		int prefix = (*i)->children.front()->token;
		switch(prefix)
		{
			case KEYWORD_O16:
				if(osz == 0)
					osz = 16;
				else
					valid = false;
				break;
			case KEYWORD_O32:
				if(osz == 0)
					osz = 32;
				else
					valid = false;
				break;
			case KEYWORD_O64:
				if(osz == 0)
					osz = 64;
				else
					valid = false;
				break;
			case KEYWORD_A16:
				if(asz == 0)
					asz = 16;
				else
					valid = false;
				break;
			case KEYWORD_A32:
				if(asz == 0)
					asz = 32;
				else
					valid = false;
				break;
			case KEYWORD_A64:
				if(asz == 0)
					asz = 64;
				else
					valid = false;
				break;
			default:
				assert(0);
				break;
		}
		
		++i;
	}
	assert((*i)->token == RULE_SIMPLE_D_STATEMENT);
	if(!valid)
	{
		throw ParseError("Too many prefix (o16/o32/o64 or a16/a32/a64).",
			stmt->lineNum,
			stmt->fileNum,
			__LINE__
		);
	}
	
	ParseNode *simple = *i;
	assert(!simple->children.empty());
	
	bool is_pure_asgn = false;
	if(simple->children.size() == 3)
	{
		i = simple->children.begin();	// possibly IDENT
		++i;							// skip possible IDENT
		if((*i)->token == '=')
			is_pure_asgn = true;
	}
	
	i = simple->children.begin();
	if(!is_pure_asgn && (*i)->token == CTokenEnums::TOKEN_IDENT)
	{
		if(osz != 0 || asz != 0)
		{
			throw ParseError("Prefix (o16/o32/o64 or a16/a32/a64) used with local variable definition.",
				stmt->lineNum,
				stmt->fileNum,
				__LINE__
			);
		}
	}
	
	std::string asgn_nm;
	ParseNode *asgn_rhs = NULL;
	
	// First allocate a local variable if that is in order.
	if(!is_pure_asgn && (*i)->token == CTokenEnums::TOKEN_IDENT)
	{
		std::string sizeid = (*i)->text;	// get identifier (size)
		++i;								// skip size identifier
		Size sz = get_exact_size(sizeid);
		if(sz.scalar == 0)
		{
			// Look up this size, it's a parameter.
			std::map<std::string, Symbol *>::iterator j = symtab2.find(sizeid);
			if(j == symtab2.end() || j->second->type != ST_ARGSIZE)
			{
				throw ParseError("Local variable size error: can't find size: " + sizeid,
					stmt->lineNum,
					stmt->fileNum,
					__LINE__
				);
			}
			sz.base = j->second->num;
			assert(sz.base < 0);
			sz.scalar = 1;
			if((*i)->token == '*')
			{
				++i;	// skip *
				sz.scalar = get_short((*i)->text);
				if(sz.scalar <= 1)
				{
					throw ParseError("Local variable size error: scalar must be 2..32767, found: " + (*i)->text,
						stmt->lineNum,
						stmt->fileNum,
						__LINE__
					);
				}
				++i;	// skip scalar
			}
		}
		else
		{
			if((*i)->token == '*')
			{
				throw ParseError("Local variable size error: can't use * with built-in type: " + sizeid,
					stmt->lineNum,
					stmt->fileNum,
					__LINE__
				);
			}
		}
		assert((*i)->token == CTokenEnums::TOKEN_IDENT);
		std::string nm = (*i)->text;
		
		// (sz, nm) now set.
		++i;
		if(i != simple->children.end())
		{
			assert((*i)->token == '=');
			++i;		// skip '='
			asgn_rhs = *i;
			asgn_nm = nm;
		}
		
		// Create local variable here.
		if(!is_valid_new_ident(nm))
		{
			throw ParseError("Local variable name already in symbol table: " + nm,
				stmt->lineNum,
				stmt->fileNum,
				__LINE__
			);
		}
		Symbol sym();
		addsym(nm, new Symbol(ST_LOCAL, insn.locals.size(), sz));
		insn.locals.push_back(sz);
		locals.insert(nm);
	}

	i = simple->children.begin();
	if(is_pure_asgn)
	{
		asgn_nm = (*i)->text;	// ident
		++i;					// skip ident
		assert((*i)->token == '=');
		++i;					// skip '='
		asgn_rhs = *i;
	}
	
	// This is used for e.g. both of these cases:
	//    zeta = undefined;
	//    bit tmp = undefined;
	if(asgn_rhs != NULL)
	{
		accept_asgn(asgn_nm, asgn_rhs, simple, insn_name, insn, asz, osz);
	}
	
	// Handle assert, push, pop, discard, outport, inport, reserve, restore here.
	i = simple->children.begin();
	if((*i)->token != CTokenEnums::TOKEN_IDENT)
	{
		int x = 0;
		switch((*i)->token)
		{
			case KEYWORD_ASSERT:
				x = SO_ASSERT;
				break;
			case KEYWORD_PUSH:
				x = SO_PUSH;
				break;
			case KEYWORD_POP:
				x = SO_POP;
				break;
			case KEYWORD_DISCARD:
				x = SO_DISCARD;
				break;
			case KEYWORD_OUTPORT:
				x = SO_OUTPORT;
				break;
			case KEYWORD_INPORT:
				x = SO_INPORT;
				break;
			case KEYWORD_RESERVE:
				x = SO_RESERVE;
				break;
			case KEYWORD_RESTORE:
				x = SO_RESTORE;
				break;
			case KEYWORD_COMMIT:
				x = SO_COMMIT;
				break;
			default:
				assert(0);
				break;
		}
		insn.stmts.push_back(Statement(x));
		Statement &stmt = insn.stmts.back();
		stmt.osz = osz;
		stmt.asz = asz;
		stmt.dest = NULL;
		
		// Now do any arguments.
		if(x == SO_RESERVE || x == SO_RESTORE)
		{
			stmt.src.push_back(Rhs());
			Rhs &outrhs = stmt.src.back();
			++i;	// skip keyword
			++i;	// skip '('
			accept_rhs(outrhs, *i, insn_name, insn, Size(8, 1));
		}
		else
		{
			++i;	// skip keyword
			++i;	// skip '('
			while((*i)->token == RULE_RHS)
			{
				stmt.src.push_back(Rhs());
				Rhs &outrhs = stmt.src.back();
				accept_rhs(outrhs, *i, insn_name, insn, Size(0, 0));
			
				if(outrhs.size.scalar == 0)
				{
					throw ParseError("Unable to resolve size of argument. If NUM, try e.g. tr<B8>(NUM)." + asgn_nm,
					simple->lineNum,
					simple->fileNum,
					__LINE__
					);
				}
			
				++i;	// skip rhs
				if((*i)->token != ',')
					break;
				++i;	// skip comma
			}
			assert((*i)->token == ')');
		}
	}
}
예제 #4
0
파일: cedric1.c 프로젝트: labmec/neopz
int main() {

   //malha geometrica
   TPZGeoMesh *firstmesh = new TPZGeoMesh;
   firstmesh->NodeVec().Resize(3);
   TPZVec<REAL> coord(2);
   coord[0] = 0.;
   coord[1] = 0.;
   //nos geometricos
   firstmesh->NodeVec()[0].Initialize(coord,*firstmesh);
   coord[0] = 1.0;
   firstmesh->NodeVec()[1].Initialize(coord,*firstmesh);
   coord[1] = 1.0;
   firstmesh->NodeVec()[2].Initialize(coord,*firstmesh);
//   coord[0] = 0.0;
//   firstmesh->NodeVec()[3].Initialize(coord,*firstmesh);
   TPZVec<int> nodeindexes(3);//triangulo
   nodeindexes[0] = 0;//local[i] = global[i] , i=0,1,2,3
   nodeindexes[1] = 1;
   nodeindexes[2] = 2;
   //elementos geometricos
   TPZGeoElT2d *elq1 = new TPZGeoElT2d(nodeindexes,1,*firstmesh);
 //orientacao local de um segundo elemento superposto
   int i,sen;;
   cout<<"Sentido local antihorario/horario : 0/1 ?  ";
   cin>>sen;
   cout<<"Entre primeiro no = 0,1,2 : ";
   cin>>i;
   if(sen==0) {//direito
        nodeindexes[0] = (0+i)%3;//local[i] = global[j] , i,j em {0,1,2}
        nodeindexes[1] = (1+i)%3;
        nodeindexes[2] = (2+i)%3;
	} else {//inverso
        nodeindexes[0] = (0+i)%3;//local[i] = global[j] , i,j em {0,1,2}
        nodeindexes[1] = (2+i)%3;
        nodeindexes[2] = (1+i)%3;
   }
/*   nodeindexes[0] = 1;//local[i] = global[i] , i=0,1,2,3
   nodeindexes[1] = 2;
   nodeindexes[2] = 3;*/
   TPZGeoElT2d *elq2 = new TPZGeoElT2d(nodeindexes,1,*firstmesh);//segundo elemento superposto ao primeiro
/*   coord[1] = 0.0;
   coord[0] = 2.0;
   firstmesh->NodeVec()[4].Initialize(coord,*firstmesh);
   coord[1] = 1.0;
   firstmesh->NodeVec()[5].Initialize(coord,*firstmesh);
   nodeindexes[0] = 1;//local[i] = global[i] , i=0,1,2,3
   nodeindexes[1] = 4;
   nodeindexes[2] = 5;
   nodeindexes[3] = 2;
   TPZGeoElT2d *elq2 = new TPZGeoElT2d(nodeindexes,1,*firstmesh);    */
   //Arquivos de saida
	ofstream outgm1("outgm1.dat");
   ofstream outcm1("outcm1.dat");
	ofstream outcm2("outcm2.dat");
   //montagem de conectividades entre elementos
   firstmesh->BuildConnectivity();
 	firstmesh->Print(outgm1);
   outgm1.flush();
  	//teste de divisao geometrica : 1 elemento
   TPZVec<TPZGeoEl *> vecsub,vecsub1;
   elq1->Divide(vecsub);//divide 0
   elq2->Divide(vecsub);//divide 1
/*   vecsub[2]->Divide(vecsub1);//
   vecsub1[3]->Divide(vecsub1);
	vecsub[0]->Divide(vecsub1);//divide 1
   vecsub1[2]->Divide(vecsub1); */
 	firstmesh->Print(outgm1);
   outgm1.flush();
   //malha computacional
   TPZCompMesh *secondmesh = new TPZCompMesh(firstmesh);
   //material
   int matindex = secondmesh->MaterialVec().AllocateNewElement();
   TPZFMatrix k(1,1,1.),f(1,1,0.),c(1,2,1.);
   TPZMat2dLin * mat = new TPZMat2dLin(1);
   mat->SetMaterial(k,c,f);
   //mat->SetForcingFunction(force);
   mat->SetForcingFunction(derivforce);
   secondmesh->MaterialVec()[matindex] = mat;
   //CC : condicao de contorno
   //ordem de interpolacao
//   TPZCompEl::gOrder = 3;
   cmesh.SetDefaultOrder(3);
   //constroe a malha computacional
   secondmesh->AutoBuild();
   secondmesh->InitializeBlock();
   secondmesh->ComputeConnectSequence();
   secondmesh->Print(outcm1);
   outcm1.flush();
	//Resolucao do sistema
   TPZFMatrix Rhs(secondmesh->NEquations(),1),Stiff(secondmesh->NEquations(),secondmesh->NEquations()),U;
   Stiff.Zero();
   Rhs.Zero();
   secondmesh->Assemble(Stiff,Rhs);
   Rhs.Print("Rhs teste",outcm2);
   Stiff.Print("Bloco teste",outcm2);
	Rhs.Print("Computational Mesh -> fBlock",outcm2);
   TPZMatrixSolver solver(&Stiff);
   solver.SetDirect(ELU);
   solver.Solve(Rhs,U);
   U.Print("Resultado",outcm2);
   secondmesh->LoadSolution(U);
   secondmesh->Solution().Print("Mesh solution ",outcm2);
//   TPZElementMatrix ek,ef;
//   secondmesh->ElementVec()[0]->CalcStiff(ek,ef);
//	ek.fMat->Print();
//   ef.fMat->Print();
   delete secondmesh;
   delete firstmesh;
   return 0;
}