Exemplo n.º 1
0
        BindingLocation existsBinding(Ptr<LispObject> pEnv,
                                      Ptr<LispObject> pSymbol)
        {
            typeCheck(pEnv, Type::Environment);
            typeCheck(pSymbol, Type::Symbol);

            auto& table = detail::getTable(pEnv);

            if(table.KeyExists(pSymbol.get()))
            {
                return BindingLocation::Local;
            }

            auto pParent = env::getParent(pEnv);

            if (!isNil(pParent))
            {
                auto location = existsBinding(pParent, pSymbol);
                if (location)
                {
                    return BindingLocation::Parent;
                }
            }

            return BindingLocation::None;
        }
Exemplo n.º 2
0
        ezResult getBinding(Ptr<LispObject> pEnv,
                            Ptr<LispObject> pSymbol,
                            Ptr<LispObject>& out_pValue)
        {
            typeCheck(pEnv, Type::Environment);
            typeCheck(pSymbol, Type::Symbol);

            auto& table = detail::getTable(pEnv);

            LispObject* pLookupResult(nullptr);
            if(table.TryGetValue(pSymbol.get(), pLookupResult))
            {
                out_pValue = pLookupResult;
                return EZ_SUCCESS;
            }

            auto pParent = env::getParent(pEnv);

            if(!isNil(pParent))
            {
                return env::getBinding(pParent, pSymbol, out_pValue);
            }

            return EZ_FAILURE;
        }
Exemplo n.º 3
0
/* Procedure typeCheck performs type checking
 * by a postorder syntax tree traversal
 */
void typeCheck(TreeNode * t)
{
	if(t != NULL)
	{
		for(int i=0;i < MAXCHILDREN ; i++)
			if(t->child[i] != NULL)
				typeCheck(t -> child[i]);
		checkNode(t);
		typeCheck(t -> sibing);
	}
}
Exemplo n.º 4
0
        void addBinding(Ptr<LispObject> pEnv,
                        Ptr<LispObject> pSymbol,
                        Ptr<LispObject> pValue)
        {
            typeCheck(pEnv, Type::Environment);
            typeCheck(pSymbol, Type::Symbol);

            auto& table = detail::getTable(pEnv);

            table[pSymbol.get()] = pValue.get();
        }
Exemplo n.º 5
0
void SemanticAnalysisVisitor::visit(ast::FunctionCall& functionCall) {
    functionCall.visitOperand(*this);
    functionCall.visitArguments(*this);

    // FIXME: try/catch for undefined functions
    auto functionSymbol = symbolTable.findFunction(functionCall.operandSymbol()->getName());

    functionCall.setSymbol(functionSymbol);

    auto& arguments = functionCall.getArgumentList();
    if (arguments.size() == functionSymbol.argumentCount()) {
        auto& declaredArguments = functionSymbol.arguments();
        for (std::size_t i { 0 }; i < arguments.size(); ++i) {
            const auto& declaredArgument = declaredArguments.at(i);
            const auto& actualArgument = arguments.at(i)->getResultSymbol();
            typeCheck(actualArgument->getType(), *declaredArgument, functionCall.getContext());
        }

        auto& returnType = functionSymbol.returnType();
        if (!returnType.isVoid()) {
            functionCall.setResultSymbol(symbolTable.createTemporarySymbol(std::unique_ptr<ast::FundamentalType> {
                    returnType.clone() }));
        }
    } else {
        semanticError("no match for function " + functionSymbol.getType().toString(), functionCall.getContext());
    }
}
Exemplo n.º 6
0
Type *multiply(Type *lhs, Type *rhs) {
	typeCheck(lhs, rhs);
	if( lhs->type == 301)
		return fmultiply(lhs, rhs);
	if( lhs->attr != NULL){
		//we cannot assign the result to a known variable here!
		//so we need to return a temp value
		Type * tmp = makeTempStruct(lhs->type);
		tmp->longval = lhs->longval * rhs->longval;
		
		/* fortunately the assembly world does not care */
		fprintf( textSec, "\tpop rax\n\timul\trax, [rsp]\n");
		fprintf( textSec, "\tmov\t[rsp], rax\n");
		
		//check name: if NULL, not id, malloc, o.w. struct remains in symtbl
		/*if(rhs->attr == NULL){
			//free malloc
			free(rhs);
			rhs = NULL;
		}*/
		return tmp;//<--should be able to trace to a free in 'declandassign.c'
	}
	lhs->longval *= rhs->longval;
	/* asm text */
  fprintf( textSec, "\tpop rax\n\timul\trax, [rsp]\n");
  fprintf( textSec, "\tmov\t[rsp], rax\n");
  
  	//check name: if NULL, not id, malloc, o.w. struct remains in symtbl
	/*if(rhs->attr == NULL){
		//free malloc
		free(rhs);
		rhs = NULL;
	}*/
  return lhs;
}
Exemplo n.º 7
0
//FUNCTION 6//Driver for typechecking.
//Traverses the tree and matches left hand side and right hand side of the assignment operators (if they are not functions, ofcourse) and gives errors in case of mismatch.
void typeCheck(tree tr)
{
    if(tr->value==ASSIGNOP)
    {
        if(tr->links[1]->value==PLUS || tr->links[1]->value==MINUS || tr->links[1]->value==MUL||tr->links[1]->value==DIV || tr->links[1]->value==SIZE || ((tr->countChildren == 2 && tr->links[0]->value==ID2 )))
        {
            int a = treetype(tr->links[0]);//Go to this function now.
            int b = treetype(tr->links[1]);
            if(a!=b && b!=funCallStmt) printf("Line %d: Type Mismatch Error in %s and %s.\n",tr->tokeninfo.line,mapTo[a],mapTo[b]);
            if(a==MATRIX && b==MATRIX && !(tr->links[1]->value==rows || tr->links[1]->value==row))
            {
                int h = matrixTreetype(tr->links[1]);
                if(h==0 || h==-1) printf("Line %d: Matrix sizes not compatible\n",tr->links[0]->tokeninfo.line);
            }
        }
        
    }
    
    else
    {
        int n = tr->countChildren;
        int i;
        for(i=0;i<n;i++)
        {
            typeCheck(tr->links[i]);
        }
    }
}
Exemplo n.º 8
0
Type *addition(Type *lhs, Type *rhs){
	typeCheck(lhs, rhs);
	if( lhs->type == 301)
		return faddition(lhs, rhs);
	if( lhs->attr != NULL){
		//we cannot assign the result to a known variable here!
		//so we need to return a temp value
		Type * tmp = makeTempStruct(lhs->type);
		tmp->longval = lhs->longval + rhs->longval;
		
		/* fortunately the assembly world does not care */
		fprintf( textSec, "\tpop\trax\n\tadd\t[rsp], rax\n");
		 //check name: if NULL, not id, malloc, o.w. struct remains in symtbl
		/*if(rhs->attr == NULL){
			//rhs is no longer needed, free the memory.
			free(rhs);
			rhs = NULL;
		}*/
		return tmp;//<--should be able to trace to a free in 'declandassign.c'
	}
	lhs->longval += rhs->longval;
	/* asm write */
  fprintf( textSec, "\tpop\trax\n\tadd\t[rsp], rax\n");
  	//check name: if NULL, not id, malloc, o.w. struct remains in symtbl
	/*if(rhs->attr == NULL){
		//rhs is no longer needed, free the memory.
		free(rhs);
		rhs = NULL;
	}*/
  return lhs;
}
 Ptr<LispObject> lowerThanOrEqual(StackPtr<LispObject> pCont)
 {
     typeCheck(pCont, Type::Continuation);
     auto pStack = cont::getStack(pCont);
     cont::setUserData(pCont, 1);
     pStack->push(LCPP_pFalse);
     LCPP_cont_tailCall(pCont, &detail::lowerThanOrEqual_helper);
 }
Exemplo n.º 10
0
        static void destroy(CollectableBase* pCollectable)
        {
            Ptr<LispObject> pObject(static_cast<LispObject*>(pCollectable));
            typeCheck(pObject, Type::Environment);

            auto& table = pObject->getData<Data>().m_table;
            table.~HashTable();
        }
Exemplo n.º 11
0
main( int argc, char * argv[] )
{ TreeNode * syntaxTree;
  char pgm[120]; /* source code file name */
  if (argc != 2) // 检查参数个数
    { fprintf(stderr,"usage: %s <filename>\n",argv[0]);
      exit(1);
    }
  strcpy(pgm,argv[1]) ;
  if (strchr (pgm, '.') == NULL) // 自动检测补全后缀
     strcat(pgm,".tny");
  source = fopen(pgm,"r");
  if (source==NULL)
  { fprintf(stderr,"File %s not found\n",pgm);
    exit(1);
  }

  // 输出导至标准输出
  listing = stdout; /* send listing to screen */
  fprintf(listing,"\nTINY COMPILATION: %s\n",pgm);
#if NO_PARSE
  while (getToken()!=ENDFILE); // 关键函数1
#else
  // parse()自己调用了getToken()
  syntaxTree = parse(); // 关键函数2
  if (TraceParse) {
    fprintf(listing,"\nSyntax tree:\n");
    printTree(syntaxTree);
  }
#if !NO_ANALYZE
  if (! Error) // Error是一个全局变量,parse()会将状态写在这里
  { if (TraceAnalyze) fprintf(listing,"\nBuilding Symbol Table...\n");
    buildSymtab(syntaxTree); // 关键函数3
    if (TraceAnalyze) fprintf(listing,"\nChecking Types...\n");
    typeCheck(syntaxTree); // 关键函数4
    if (TraceAnalyze) fprintf(listing,"\nType Checking Finished\n");
  } // 上面这两个函数可以看成一个整体,输入是一棵语法树,输出是一颗带标记的语法树,和一张符号表
#if !NO_CODE
  if (! Error) // 又是一次错误检查
  { char * codefile;
    // 组建输出文件的文件名
    int fnlen = strcspn(pgm,".");
    codefile = (char *) calloc(fnlen+4, sizeof(char));
    strncpy(codefile,pgm,fnlen);
    strcat(codefile,".tm");
    code = fopen(codefile,"w");
    if (code == NULL)
    { printf("Unable to open %s\n",codefile);
      exit(1);
    }
    codeGen(syntaxTree,codefile); // 关键函数5
    fclose(code);
  }
#endif
#endif
#endif
  fclose(source);
  return 0;
}
Exemplo n.º 12
0
        Ptr<LispObject> create(StackPtr<LispObject> pParent,
                               StackPtr<LispObject> pName)
        {
            LCPP_LogBlock("env::create");

            if(!isNil(pParent)) typeCheck(pParent, Type::Environment);
            typeCheck(pName, Type::Symbol);

            auto pInstance = object::create<Data>(getMetaInfo());

            LCPP_GC_PreventCollectionInScope;

            auto& data = pInstance->getData<Data>();

            data.m_pName = pName.get();
            data.m_pParent = pParent.get();

            return pInstance;
        }
Exemplo n.º 13
0
int main(int argc, char *argv[]) {
  char pgm[20];
  if(argc != 2)
  { fprintf(stderr, "usage: %s <filename>\n", argv[0]);
    exit(1);
  }
  
  strcpy(pgm, argv[1]);
  source = fopen(pgm, "r");
  if(source == NULL) 
  { fprintf(stderr, "File %s not found\n", pgm);
    exit(1);
  }
  
  listing = stdout; /* send listing to screen */
  fprintf(listing, "\nC-MINUS COMPILATION: %s\n", pgm);
  
#if NO_PARSE
  while(getToken() != ENDFILE);
#else
  syntaxTree = parse();
  if (TraceParse) {
    fprintf(listing,"\nSyntax tree:\n");
    printTree(syntaxTree);
  }
#if !NO_ANALYZE
  if (! Error)
  { if (TraceAnalyze) fprintf(listing,"\nBuilding Symbol Table...\n");
    buildSymtab(syntaxTree);
    if (TraceAnalyze) fprintf(listing,"\nChecking Types...\n");
    typeCheck(syntaxTree);
    if (TraceAnalyze) fprintf(listing,"\nType Checking Finished\n");
  }
#if !NO_CODE
  if (! Error)
  { char * codefile;
    int fnlen = strcspn(pgm,".");
    codefile = (char *) calloc(fnlen+4, sizeof(char));
    strncpy(codefile,pgm,fnlen);
    strcat(codefile,".tm");
    code = fopen(codefile,"w");
    if (code == NULL)
    { printf("Unable to open %s\n",codefile);
      exit(1);
    }
    codeGen(syntaxTree,codefile);
    fclose(code);
  }
#endif
#endif
#endif
  fclose(source);
  return 0;
  return 0;
}
Exemplo n.º 14
0
int main(int argc, char** argv){
	int i, j, ws, fd, o_direct;
	if (argc != 4){
		printf(ARGS_ERROR);
		return -1;
	}
	if (typeCheck(argv[1]) == -1){
		return -1;
	}
	if (!(strcmp(argv[2], "1") == 0 || strcmp(argv[2], "0") == 0)){
		printf(ARG_ERROR, argv[2]);
		return -1;
	}
	ws = atoi(argv[3]);
	if (!ws){ // ws == 0
		printf(ARG_ERROR, argv[3]);
		return -1;
	}
	static char buf[MB] __attribute__((__aligned__(4096)));
	for (j = 0; j < MB; j++) buf[i] = 'a' + (random() % 26);


	struct timeval t1, t2; //referance: http://stackoverflow.com/questions/2150291/how-do-i-measure-a-time-interval-in-c, first answer
	double elapsedTime;
	gettimeofday(&t1, NULL); // start timer

	o_direct = atoi(argv[2]);
	if (o_direct) fd = open(argv[1], O_WRONLY | O_DIRECT, S_IRWXU | S_IRWXG | S_IRWXO);
	else  fd = open(argv[1], O_WRONLY, S_IRWXU | S_IRWXG | S_IRWXO);
	if (fd == -1){
		printf(OPEN_ERROR, argv[2], strerror(errno));
		return -1;
	}
	int repeats = (128 * MB) / (ws * KB);
	for (i = 0; i < repeats; i++){
		int offset = (random() % repeats) * ws;
		if (lseek(fd, offset, SEEK_SET) == (off_t)-1){
			printf(SEEK_ERROR, argv[1], strerror(errno));
			close(fd);
			return -1;
		}
		if (write(fd, buf, ws) == -1){
			printf(WRITE_ERROR, argv[1], strerror(errno));
			close(fd);
			return -1;
		}
	}
	close(fd);

	gettimeofday(&t2, NULL);
	elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;      // sec to ms
	elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;   // us to ms
	printf(THROUGHPUT, elapsedTime);
	return 0;
}
Exemplo n.º 15
0
void typeChecker(tree tr)
{
    currMax = 1;
    scope = 1;
    dummy = 0;
    table = createHashTable(); 
    strcpy(mapV[1],"_main");  
    param = &dummy;
    Populate(tr,1); //Start from this function. 
    typeCheck(tr); //Then this one.
}
Exemplo n.º 16
0
void SemanticAnalysisVisitor::visit(ast::LogicalOrExpression& expression) {
    expression.visitLeftOperand(*this);
    expression.visitRightOperand(*this);

    typeCheck(
            expression.leftOperandType(),
            expression.rightOperandType(),
            expression.getContext());

    expression.setResultSymbol(symbolTable.createTemporarySymbol(ast::IntegralType::newSignedInteger()));
    expression.setExitLabel(symbolTable.newLabel());
}
Exemplo n.º 17
0
void SemanticAnalysisVisitor::visit(ast::BitwiseExpression& expression) {
    expression.visitLeftOperand(*this);
    expression.visitRightOperand(*this);
    expression.setType(expression.leftOperandType());

    typeCheck(
            expression.leftOperandType(),
            expression.rightOperandType(),
            expression.getContext());

    expression.setResultSymbol(
            symbolTable.createTemporarySymbol(std::unique_ptr<ast::FundamentalType> { expression.getType().clone() }));
}
Exemplo n.º 18
0
        ezResult setBinding(Ptr<LispObject> pEnv,
                            Ptr<LispObject> pSymbol,
                            Ptr<LispObject> pValue)
        {
            typeCheck(pEnv, Type::Environment);
            typeCheck(pSymbol, Type::Symbol);

            auto& table = detail::getTable(pEnv);

            if(table.KeyExists(pSymbol.get()))
            {
                table[pSymbol.get()] = pValue.get();
                return EZ_SUCCESS;
            }

            auto pParent = getParent(pEnv);

            if(!isNil(pParent))
            {
                return setBinding(pParent, pSymbol, pValue);
            }

            return EZ_FAILURE;
        }
Exemplo n.º 19
0
void SemanticAnalysisVisitor::visit(ast::AssignmentExpression& expression) {
    expression.visitLeftOperand(*this);
    expression.visitRightOperand(*this);

    if (expression.isLval()) {
        typeCheck(
                expression.leftOperandType(),
                expression.rightOperandType(),
                expression.getContext());

        expression.setResultSymbol(*expression.leftOperandSymbol());
    } else {
        semanticError("lvalue required on the left side of assignment", expression.getContext());
    }
}
Exemplo n.º 20
0
        Ptr<LispObject> getQualifiedName(Ptr<LispObject> pEnv)
        {
            typeCheck(pEnv, Type::Environment);

            auto name = ezStringBuilder();

            while(true)
            {
                name.Prepend(symbol::getValue(getName(pEnv)).GetData());
                pEnv = getParent(pEnv);
                if(isNil(pEnv))
                {
                    break;
                }
                name.Prepend('/');
            }

            return str::create(name.GetData(), name.GetElementCount());
        }
Exemplo n.º 21
0
/* performs div by zero error check*/
Type *divide(Type *lhs, Type *rhs){
	typeCheck(lhs, rhs);
	if( lhs->type == 301)
		return fdivide(lhs, rhs);
	if (rhs->longval == 0 && !FLAG_FUN ) /* must ignore if defining a function */
		printError("Divide by Zero!\0", 1 );
	if( lhs->attr != NULL){
		//we cannot assign the result to a known variable here!
		//so we need to return a temp value
		Type * tmp = makeTempStruct(lhs->type);
		/* due to interactive nature of language, 
		--floating point exception-- thrown when defining functions */
		if( !FLAG_FUN ){ 
			tmp->longval = lhs->longval / rhs->longval;
		}
		
		/* fortunately the assembly world does not care */
		fprintf( textSec, "\txor\trdx, rdx\n\tpop\trbx\n");
		fprintf( textSec, "\tpop rax\n\tcqo\n\tidiv\tQWORD rbx\n");
		fprintf( textSec, "\tpush\tQWORD rax\n");
		//check name: if NULL, not id, malloc, o.w. struct remains in symtbl
		/*if(rhs->attr == NULL){
			//free rhs memory
			free(rhs);
			rhs = NULL;
		}*/
		return tmp;//<--should be able to trace to a free in 'declandassign.c'
	}
	lhs->longval /= rhs->longval;

	/* asm write */
  fprintf( textSec, "\txor\trdx, rdx\n\tpop\trbx\n");
  fprintf( textSec, "\tpop rax\n\tcqo\n\tidiv\tQWORD rbx\n");
  fprintf( textSec, "\tpush\tQWORD rax\n");
	//check name: if NULL, not id, malloc, o.w. struct remains in symtbl
	/*if(rhs->attr == NULL){
		//free rhs memory
		free(rhs);
		rhs = NULL;
	}*/
  return lhs;
}
Exemplo n.º 22
0
        static void scan(CollectableBase* pCollectable, GarbageCollectionContext* pGC)
        {
            static ezUInt32 uiScanCount(0);
            ++uiScanCount;

            auto pObject = reinterpret_cast<LispObject*>(pCollectable);
            typeCheck(pObject, Type::Environment);

            // Note: Symbols are not garbage collected.

            auto& pParent = pObject->getData<Data>().m_pParent.get();
            pParent = pGC->addSurvivor(pParent);

            auto& table = detail::getTable(pObject);
            for (auto iter = table.GetIterator(); iter.IsValid(); ++iter)
            {
                auto& pValue = iter.Value();
                pValue = pGC->addSurvivor(pValue);
            }
        }
Exemplo n.º 23
0
int main(){
// ningning
    source = fopen(filename,"r");
    listing=stdout;
    TreeNode * syntaxTree;
 //   while(getToken()!=ENDFILE);
    syntaxTree = parse();
    printTree(syntaxTree);  

// type check
    typeCheck(syntaxTree);

// caihua
//  if(!error)
		CG_main(syntaxTree,"out.asm");
//	else
//		printf("Info: compiling exit with errors!");

    return 0;
}
Exemplo n.º 24
0
/* performs idiv and pushes remainder register (rdx)*/
Type *mod(Type *lhs, Type *rhs){
	typeCheck(lhs, rhs);
	if (rhs->longval == 0)
		printError("Mod by Zero!\0", 1 );
	if( lhs->type == 301){
		/* language does not support floating point modulus */
		printError( "Language does not support float modulus", 1);
	}
	if( lhs->attr != NULL){
		//we cannot assign the result to a known variable here!
		//so we need to return a temp value
		Type * tmp = makeTempStruct(lhs->type);
		tmp->longval = lhs->longval % rhs->longval;
		
		/* fortunately the assembly world does not care */
		fprintf( textSec, "\txor\trdx, rdx\n\tpop\trbx\n"); 
		fprintf( textSec, "\tpop\trax\n\tidiv\trbx\n\tpush\trdx\n");
		//check name: if NULL, not id, malloc, o.w. struct remains in symtbl
		/*if(rhs->attr == NULL){
			//free rhs memory
			free(rhs);
			rhs = NULL;
		}*/
		return tmp;//<--should be able to trace to a free in 'declandassign.c'
	}
	lhs->longval %= rhs->longval;

	/* asm write */
  fprintf( textSec, "\txor\trdx, rdx\n\tpop\trbx\n"); 
  fprintf( textSec, "\tpop\trax\n\tidiv\trbx\n\tpush\trdx\n");
  //check name: if NULL, not id, malloc, o.w. struct remains in symtbl
  	/*if(rhs->attr == NULL){
		//free rhs memory
		free(rhs);
		rhs = NULL;
	}*/
	return lhs;
}
Exemplo n.º 25
0
int main(int argc, char * argv[]) {
  char pgm[20]; /* source code file name */
  TreeNode* syntaxTree;

  if (argc !=2) {
    fprintf(stderr, "usage: %s <filename>\n", argv[0]);
    exit(1);
  }
  strcpy(pgm, argv[1]);
  source = fopen(pgm,"r");
  if (source == NULL) {
    fprintf(stderr, "File %s not found\n", pgm);
    exit(1);
  }
  listing = stdout;
  //while(getToken()!=ENDFILE);
  syntaxTree = parse();
  if (syntaxTree == NULL) fprintf(listing,"syntaxTree is Null\n");
  
  if (TraceParse) {
    fprintf(listing,"\nSyntax tree:\n");
    printTree(syntaxTree);
  }
  
  if(!Error){
    /* 
     * fprintf(listing,"\nBuilding symbol table...\n");
     * buildSymtab(syntaxTree);
     */
    fprintf(listing,"\nChecking type...\n");
    typeCheck(syntaxTree);
    fprintf(listing,"\nChecking type finished...\n");
  }  

  return 1;
}
Exemplo n.º 26
0
int main(int argc, char **argv)
{
    /* Handle the fiddliness of command line arguments elsewhere */
    if (ParseCommandLine(argc, argv) != 0)
    {
        usage();
        exit(1);
    }

    /* If the supplied filename lacks an extension, add one. */
    if (strchr(sourceFileName, '.') == NULL)
	strcat(sourceFileName, ".cm");

    /* Open the source file */
    source = fopen(sourceFileName, "r");

    /* If it failed, bomb out. */
    if (source == NULL)
    {
	fprintf(stderr, "Sorry, but the source file %s could not be found.\n",
		sourceFileName);
	exit(1);
    };

    /* By default, send output to standard output */
    listing = stdout;

    fprintf(listing, COPYRIGHT "\n");
    fprintf(listing, "*** C- COMPILATION: %s\n", sourceFileName);
    fprintf(listing, "*** Compiler built as " BUILDTYPE " version.\n");

    /* If the compiler was built scanner-only, then only run the scanner */
#if NO_PARSE
    while (getToken() != ENDOFFILE)
    {
        /* do nothing */
    };
#else
    fprintf(listing, "*** Parsing source program...\n");
    syntaxTree = Parse();

    /* Tracing enabled?  Let's have it... */
    if (TraceParse)
    {
        fprintf(listing, "*** Dumping syntax tree\n");
	printTree(syntaxTree);
    };

#if !NO_ANALYSE
    if (!Error)
    {
	fprintf(listing, "*** Building symbol table...\n");
	buildSymbolTable(syntaxTree);
	fprintf(listing, "*** Performing type checking...\n");
	typeCheck(syntaxTree);
    }

#if !NO_CODE
    if (!Error)
    {
	codeGen(syntaxTree, "output.dcl", "output");

	/* did code generation succeed? */
	if (!Error)
	{
	    fprintf(listing,"*** Output written to \"output.dcl\"\n");

	    /* tracing? remind user */
	    if (TraceCode)
		fprintf(listing,
			"*** CODE TRACING OPTION ENABLED; see output\n");
	}
    }
    
#endif    
#endif
#endif
    
    if (!Error)
        fprintf(listing,"*** COMPILATION COMPLETE: %d lines processed.\n", 
                lineno);
    else
        fprintf(listing,"*** ERRORS WERE ENCOUNTERED: %d lines processed.\n", 
                lineno);
    
    return EXIT_SUCCESS;
}
Exemplo n.º 27
0
/****type checking****/
void typeCheck(TreeNode* node)
{
    TreeNode* argPtr=NULL;
    StPara* stParaPtr=NULL;
    StNode* stPtr;
    int i;
    /***postorder travel***/
    for(i=0;i<MAXCHILDREN;i++){
        if(node->child[i]!=NULL){
            typeCheck(node->child[i]);
        }
    }
    /***check***/
    switch(node->kind){
    case DeclK:{
    /*declaration, already have types, no operation*/
        switch(node->subkind.declType){
        case SimVarDcl:{
            break;
        }
        case ArrVarDcl:{
            break;
        }
        case FunDcl:{
            break;
        }
        }
    break;
    }
    case ParaK:{
        /*parameters, already have types, no operation*/
        switch(node->subkind.paraType){
        case Simple:{
            
            break;
        }
        case Array:{
            
            break;
        }
        }
    break;
    }
    case StmtK:{
        switch(node->subkind.stmtType){
        case ComStmt:{
        /*compound statement, nothing to check*/
            if(node->child[0]!=NULL)
                node->type=node->child[0]->type;
            else{}
            break;
        }
        case ExprStmt:{
        /*expression statement, nothing to check*/
            if(node->child[0]!=NULL)
                node->type=node->child[0]->type;
            break;
        }
        case SeleStmt:{
        /*if statement, check if the condition is boolean*/
            if(node->child[0]->type!=Boolean){
                printf("error:line %d:condition must be a boolean value\n",node->lineno);
                Error=1;
            }
            
            break;
        }
        case IterStmt:{
        /*while statement, check if the condition is boolean*/
            if(node->child[0]->type!=Boolean){
                printf("error:line %d:condition must be a boolean value\n",node->lineno);
                Error=1;
            }
            break;
        }
        case ReturnStmt:{
        /*reutrn statement, check if the type is compatible with the funcation declaration*/
            if(node->child[0]==NULL){
                if(node->handle->funType!=Void){
                    printf("error:line %d:return value not compatible\n",node->lineno);
                    Error=1;
                }
            }
            else{
                node->type=node->child[0]->type;
                if(node->handle->funType!=node->child[0]->type){
                    printf("error:line %d:return value not compatible\n",node->lineno);
                    Error=1;
                }
            }
            break;
        }
        }
    break;
    }
    case ExprK:{
        switch(node->subkind.exprType){
        case AssignExp:{
        /*assigment expresstion, check if the type is compatible*/
            if(node->child[0]->type!=node->child[1]->type){
                printf("error:line %d:type error while assign to %s\n",node->lineno,node->child[0]->attr.name);
                Error=1;
            }
            node->type=node->child[0]->type;
            break;
        }
        case SimpExp:{
            if(node->child[1]==NULL){
                /***just one expresstion***/
                node->type=node->child[0]->type;
            }
            else{
                if(node->child[0]->type!=node->child[1]->type){
                    printf("error:line %d:operand type not compatible\n",node->lineno);
                    Error=1;
                }
                node->type=Boolean;
            }
            break;
        }
        }
    break;
    }
    case VarK:{
        switch(node->subkind.varType){
        /**variables, check if it is declared**/
        case ArrayVar:{
            stPtr=stLookup(node->handle,node->attr.name);
            if(stPtr==NULL){
                printf("error:line %d:%s has not been declared as a variable\n",node->lineno,node->attr.name);
                Error=1;
                node->type=Integer;
            }
            else{
                if(stPtr->type==IntArray)
                    node->type=Integer;
                else if(stPtr->type==VoidArray)
                    node->type=Void;
                else
                    node->type=Boolean;
            }
            break;
        }
        case SimpVar:{
            stPtr=stLookup(node->handle,node->attr.name);
            if(stPtr==NULL){
                printf("error:line %d:%s is not a variable\n",node->lineno,node->attr.name);
                Error=1;
                node->type=Integer;
            }
            else{
                node->type=stPtr->type;
            }
            break;
        }
        }
    break;
    }
    case AddexprK:{
        if(node->child[0]->type!=node->child[1]->type){
            printf("error:line %d:operand type not compatible\n",node->lineno);
            Error=1;
        }
        node->type=node->child[0]->type;
        break;
    }
    case TermK:{
        switch(node->subkind.termType){
        case Multiple:{
            /***term type with mulop, check if two operand is compatible**/
            if(node->child[0]->type!=node->child[1]->type){
                printf("error:line %d:operand type not compatible\n",node->lineno);
                Error=1;
            }
            node->type=node->child[0]->type;
            break;
        }
        case Single:{
        /**single factor, just assign type**/
            node->type=node->child[0]->type;
            break;
        }
        }
    break;
    }
    case FactK:{
        switch(node->subkind.factorType){
        case Expr:{
        /**expression, **/
            node->type=node->child[0]->type;
            break;
        }
        case Var:{
        /**variable, assign type of variable**/
            node->type=node->child[0]->type;
            break;
        }
        case Call:{
        /**call factor, assign the type of the function**/
            node->type=node->child[0]->type;
            break;
        }
        case Num:{
        /**just a Integer**/
            node->type=Integer;
            break;
        } 
        }
    break;
    }
    case CallK:{
    /***call function***/
        stPtr=stLookup(node->handle,node->attr.name);
        if(stPtr==NULL || stPtr->isFun==0){
        /**check if the function is declared**/
            printf("error: line %d: %s is not a function name\n",node->lineno,node->attr.name);
            Error=1;
            node->type=Integer;
        }
        else{
            /**check if the arguements is all right**/
            argPtr=node->child[0];
            stParaPtr=stPtr->para;
            while(argPtr!=NULL && stParaPtr!=NULL){
                if(argPtr->type!=stParaPtr->type){
                    printf("error:line %d:arguement type not compatible\n",node->lineno);
                    Error=1;
                }
                argPtr=argPtr->sibling;
                stParaPtr=stParaPtr->next;
            }
            if(argPtr!=NULL || stParaPtr!=NULL){
                printf("error:line %d:arguement number not compatible\n",node->lineno);
                    Error=1;
            }
            node->type=stPtr->type;
        }
        break;
    }
    case ArgsK:{
        break;
    }
    }
    /*****travel the sibling******/

    if(node->sibling!=NULL){
        typeCheck(node->sibling);
    }
}
Exemplo n.º 28
0
// This function evaluates the parse tree given by expr within the given environment.
Value* eval(Value *expr, Environment *env){
  Value* operator;
  Value* args;
  //printf("Here is expression:  ");
  //printValue(expr);
  //printf("\n");
  
  if (!expr){
    return NULL;
  }
  
  switch (expr->type) 
    {
    case symbolType:
      //printf("unknown identifier");
      args = envLookup(expr->symbolValue, env);
      if (args){
	//printf("going here\n");
	//printValue(expr);
	//printf("\nending here\n");
	return args;
      }
      else{
	printf("syntax error: unknown identifier");
	return NULL;
      }
      break;
    case cellType:
      if (expr->cons->car->type == nullType) {
	return expr->cons->car;
      }
      //printf("Here is expression:  ");
      //printValue(getFirst(expr));
      //printf("\n");
      
      if (getFirst(expr) != NULL && getFirst(expr)->type == openType) {
	operator = car(expr);

	if (!operator){
	  printf("syntax error, missing components here");
	  return NULL;
	}
	if (operator->type == cellType){
	  operator = eval(operator, env);
	}
	
	if (operator->type == symbolType){
	  args = getTail(getTail(expr));
	  //printf("checking args?: ");
	  //printValue(args);
	  //printf("\n"); //if (args  == NULL){
	  //return eval(operator,env); //	  }else 
	  if (strcmp(operator->symbolValue,"define")==0){
	    return evalDefine(args, env);
	  }else if (strcmp(operator->symbolValue,"lambda")==0){
	    /*eval lambda goes here*/
	    return evalLambda(args, env);
	  }else if (strcmp(operator->symbolValue,"if")== 0){
	    return evalIf(args, env);
	    /*eval if goes here*/
	  }else if (strcmp(operator->symbolValue,"quote")==0){
	    /*eval quote goes here*/
	    return evalQuote(args);
	  }else if (strcmp(operator->symbolValue,"let")==0){
	    /*eval let goes here*/
	    return evalLet(args, env);
	  }else{
	    //printf("validation result is shown: %d\n",validateArgs(args, env));
	    if (validateArgs(args, env)==-1){
	      printf("Syntax error! Invalid arguments for the procedure: ");
	      printValue(operator);
	      printf("\n");
	      return NULL;
	    } 
	    Value *evaledOperator = eval(operator, env);
	    Value *evaledArgs = evalEach(args, env);
	    if (!evaledOperator){
	      printf("Unknown procedure: ");
	      printValue(operator);
	      printf("\n");
	    }
	    //printValue(evaledArgs);
	    //printf("\n");
	    return apply(evaledOperator, evaledArgs);
	  }
	}else if (typeCheck(operator)==1){
	  printf("A literal ");
	  printValue(operator);
	  printf(" cannot be a procedure.\n");
	  return NULL; 
	}
      } else if (typeCheck(getFirst(expr))==1){
	//printValue(expr);
	//printf("\n");
	return evalEach(expr,env);
      }else if (getFirst(expr) && getFirst(expr)->type ==cellType && getFirst(getTail(expr)) && getFirst(getTail(expr))->type==closeType){
	return eval(getFirst(expr),env);
      }else if (getFirst(expr) && getFirst(expr)->type == symbolType){
	operator = getFirst(expr);
	Value *returnValue = envLookup(operator->symbolValue, env);
	
	if (returnValue){
	  return returnValue;
	}else{
	  if (strcmp(operator->symbolValue,"define")==0){
	    printf("define: bad syntax in ");
	    printValue(expr);
	    printf("\n");
	  }else if (strcmp(operator->symbolValue,"lambda")==0){
	    printf("lambda: bad syntax in ");
	    printValue(expr);
	    printf("\n");
	  }else if (strcmp(operator->symbolValue,"if")==0){
	    printf("if: bad syntax in ");
	    printValue(expr);
	    printf("\n");
	  }else if (strcmp(operator->symbolValue,"quote")==0){
	    printf("quote: bad syntax in ");
	     printValue(expr);
	     printf("\n");
	  }else if (strcmp(operator->symbolValue,"let")==0){
	     printf("let: bad syntax in ");
	     printValue(expr);
	     printf("\n");
	  }else{
	     
	    printf("Unknown identifier %s.\n",operator->symbolValue);
	   }
	  
	   return NULL;
	 }
       }
       
    case closeType:
      //printValue(expr);
      //printf("\n");
      return NULL;
      break;
    default:
      //printValue(expr);
      //printf("\n");
      if (getTail(expr)){
	assert(getFirst(getTail(expr))!=NULL);
	assert(getFirst(getTail(expr))->type==closeType);
	Value *toRemove = getTail(expr);
	free(toRemove->cons->car);
	free(toRemove->cons);
	free(toRemove);
	expr->cons->cdr = NULL;
	//assert(1==2);
      }
      return expr;      
    }
}
Exemplo n.º 29
0
bool DCOPReply::typeCheck(const char *t)
{
    return typeCheck(t, true);
}
Exemplo n.º 30
0
/*
  pop exponent into rcx (loop counter), pop base into rax, cp rax to r8,
  loop til counter == 0 and push result (rax)
  MODIFIES lhs->dubval and rhs->dubval (note for future planning)
				^^^ would have to save value before calling fdivide()
*/
Type *power(Type *lhs, Type *rhs){
	Type *tmp;//points to lhs if lhs->attr == NULL, o.w. points to malloc type*
	Type *tempHolder; //UNUSED BUT HERE WHEN WE DECIDE IT'S NECESSARY
	int negFlag = 0; //set to 1 when lhs is negative
	typeCheck(lhs, rhs);
	if( lhs->type == 301)
		return fpower(lhs, rhs);
	/* USING special trick because the pow funct is messy */
	if( lhs->attr != NULL){
		
		//we cannot assign the result to a known variable here!
		//so we need to return a temp value
		tmp = makeTempStruct(lhs->type);
		tmp->longval = lhs->longval;
	}
	else{
		tmp = lhs;
	}
	if( lhs->longval < 0 ){
		tmp->longval = -tmp->longval;
		negFlag = 1; //set negative flag
		fprintf( textSec, "\tneg\tQWORD [rsp + 8]\n");
	}
	if( rhs->longval < 0 ){
		/* Do something special because assembly code fails */
		// (1) complement the complement
		rhs->longval = -rhs->longval;
		//x^(-p) <==> (HERE) 1/(x^(p))  ==> fdivide( 1, (x^(p) )
		tmp->longval = pow(tmp->longval, rhs->longval);
		//restore rhs value
		rhs->longval = -rhs->longval;
		fprintf( textSec, "\tneg\tQWORD [rsp]\n");
		fprintf( textSec, "\tpop\trcx\n\tpop rdi\n\tcall\tloopPow\n");
		// may need to have storage in .data for these two below
		fprintf( textSec, "\tpush QWORD 1\n\tpush\trax\n");
		//x^(-p) <==> 1/(x^(p)) (HERE) ==> fdivide( 1, (x^(p) )
		rhs->dubval = 1.0;
		// lhs = (double) lhs->longval
		tmp->dubval = tmp->longval;
		//x^(-p) <==> 1/(x^(p)) ==> fdivide( 1, (x^(p) )  (HERE)
		//=====================================================
		rhs->dubval /= tmp->dubval;
		/* asm write */
		fprintf( textSec, "\tfld\tQWORD [rsp + 8]\n");
		//push value into st(0)
		fprintf( textSec, "\tfld\tQWORD [rsp]\n");
		fprintf( textSec, "\tadd\trsp, 8\n");
		fprintf( textSec, "\t;div the previous st0 w/ top and discard top\n");
		fprintf( textSec, "\tfdivp\tst1, st0\n");
		//pop FPU stack and store INTEGER in rsp
		fprintf( textSec, "\tfistp\tQWORD [rsp] ;converts float to int!!!\n");
		//=====================================================
		//trucate the result back to an integer
		tmp->longval = (int) rhs->dubval;
		//restore values of lhs->dubval and rhs->dubval
		/* lhs->dubval = savedlhsDUBVAL 
		   rhs->dubval = savedrhsDUBVAL */
		// if lhs is negative and exponent is odd...
		if( negFlag && rhs->longval % 2 ){
			tmp->longval = -tmp->longval;
			/* asm write */
			fprintf( textSec, "\tneg\tQWORD [rsp]\n");
		}
		/* pffffeww... */
		return tmp;
	}
	
	/* update value in symbol table */
	tmp->longval = pow(lhs->longval, rhs->longval);
	/* asm write */
	fprintf( textSec, "\tpop\trcx\n\tpop rdi\n\tcall\tloopPow\n");
	fprintf( textSec, "\tpush\trax\n");
	// if lhs is negative and exponent is odd...
	if( negFlag && rhs->longval % 2 ){
		tmp->longval = -tmp->longval;
		/* asm write */
		fprintf( textSec, "\tneg\tQWORD [rsp]\n");
	}
	//check name: if NULL, not id, malloc, o.w. struct remains in symtbl
  	//if(rhs->attr == NULL)
		//rhs is no longer needed, free the memory.
		/*free(rhs);*/
		//rhs = NULL;
	return tmp;
}