void compileParam(void) {
    // TODO: create and declare a parameter
    Object* obj = NULL;
    switch (lookAhead->tokenType) {
    case TK_IDENT:
        eat(TK_IDENT);
        obj = createParameterObject(currentToken->string, PARAM_VALUE, symtab->currentScope->owner);
        eat(SB_COLON);

        obj->paramAttrs->type = compileBasicType();
        declareObject(obj);
        break;
    case KW_VAR:
        eat(KW_VAR);
        eat(TK_IDENT);
        obj = createParameterObject(currentToken->string, PARAM_REFERENCE, symtab->currentScope->owner);
        eat(SB_COLON);

        obj->paramAttrs->type = compileBasicType();
        declareObject(obj);
        break;
    default:
        error(ERR_INVALID_PARAMETER, lookAhead->lineNo, lookAhead->colNo);
        break;
    }
}
void compileFuncDecl(void) {
  Object* funcObj;
  Type* returnType;
  
  eat(KW_FUNCTION);
  eat(TK_IDENT);
  // TODO: Check if a function identifier is fresh in the block
  checkFreshIdent(currentToken->string);
  // create the function object
  funcObj = createFunctionObject(currentToken->string);
  // declare the function object
  declareObject(funcObj);
  // enter the function's block
  enterBlock(funcObj->funcAttrs->scope);
  // parse the function's parameters
  compileParams();
  eat(SB_COLON);
  // get the funtion's return type
  returnType = compileBasicType();
  funcObj->funcAttrs->returnType = returnType;

  eat(SB_SEMICOLON);
  compileBlock();
  eat(SB_SEMICOLON);
  // exit the function block
  exitBlock();
}
void compileBlock(void) {
  Object* constObj;
  ConstantValue* constValue;

  if (lookAhead->tokenType == KW_CONST) {
    eat(KW_CONST);

    do {
      eat(TK_IDENT);
      
      checkFreshIdent(currentToken->string);
      constObj = createConstantObject(currentToken->string);
      
      eat(SB_EQ);
      constValue = compileConstant();
      
      constObj->constAttrs->value = constValue;
      declareObject(constObj);
      
      eat(SB_SEMICOLON);
    } while (lookAhead->tokenType == TK_IDENT);

    compileBlock2();
  } 
  else compileBlock2();
}
void compileParam(void) {
  Object* param;
  Type* type;
  enum ParamKind paramKind;

  switch (lookAhead->tokenType) {
  case TK_IDENT:
    paramKind = PARAM_VALUE;
    break;
  case KW_VAR:
    eat(KW_VAR);
    paramKind = PARAM_REFERENCE;
    break;
  default:
    error(ERR_INVALID_PARAMETER, lookAhead->lineNo, lookAhead->colNo);
    break;
  }

  eat(TK_IDENT);
  checkFreshIdent(currentToken->string);
  param = createParameterObject(currentToken->string, paramKind, symtab->currentScope->owner);
  eat(SB_COLON);
  type = compileBasicType();
  param->paramAttrs->type = type;
  declareObject(param);
}
void compileFuncDecl(void) {
  Object* funcObj;
  Type* returnType;

  eat(KW_FUNCTION);
  eat(TK_IDENT);

  checkFreshIdent(currentToken->string);
  funcObj = createFunctionObject(currentToken->string);
  declareObject(funcObj);

  enterBlock(funcObj->funcAttrs->scope);
  
  compileParams();

  eat(SB_COLON);
  returnType = compileBasicType();
  funcObj->funcAttrs->returnType = returnType;

  eat(SB_SEMICOLON);
  compileBlock();
  eat(SB_SEMICOLON);

  exitBlock();
}
void compileBlock3(void) {
  Object* varObj;
  Type* varType;
  
  if (lookAhead->tokenType == KW_VAR) {
    eat(KW_VAR);
    
    do {
      eat(TK_IDENT);
      // TODO: Check if a variable identifier is fresh in the block
      checkFreshIdent(currentToken->string);
      // Create a variable object      
      varObj = createVariableObject(currentToken->string);
      
      eat(SB_COLON);
      // Get the variable type
      varType = compileType();
      varObj->varAttrs->type = varType;
      // Declare the variable object
      declareObject(varObj);
      
      eat(SB_SEMICOLON);
    } while (lookAhead->tokenType == TK_IDENT);
    
    compileBlock4();
  } 
  else compileBlock4();
}
void compileBlock3(void) {
  Object* varObj;
  Type* varType;

  if (lookAhead->tokenType == KW_VAR) {
    eat(KW_VAR);

    do {
      eat(TK_IDENT);
      
      checkFreshIdent(currentToken->string);
      varObj = createVariableObject(currentToken->string);

      eat(SB_COLON);
      varType = compileType();
      
      varObj->varAttrs->type = varType;
      declareObject(varObj);
      
      eat(SB_SEMICOLON);
    } while (lookAhead->tokenType == TK_IDENT);

    compileBlock4();
  } 
  else compileBlock4();
}
void compileBlock2(void) {
  Object* typeObj;
  Type* actualType;

  if (lookAhead->tokenType == KW_TYPE) {
    eat(KW_TYPE);

    do {
      eat(TK_IDENT);
      // TODO: Check if a type identifier is fresh in the block
      checkFreshIdent(currentToken->string);
      // create a type object
      typeObj = createTypeObject(currentToken->string);
      
      eat(SB_EQ);
      // Get the actual type
      actualType = compileType();
      typeObj->typeAttrs->actualType = actualType;
      // Declare the type object
      declareObject(typeObj);
      
      eat(SB_SEMICOLON);
    } while (lookAhead->tokenType == TK_IDENT);
    
    compileBlock3();
  } 
  else compileBlock3();
}
void compileBlock2(void) {
  Object* typeObj;
  Type* actualType;

  if (lookAhead->tokenType == KW_TYPE) {
    eat(KW_TYPE);

    do {
      eat(TK_IDENT);
      
      checkFreshIdent(currentToken->string);
      typeObj = createTypeObject(currentToken->string);
      
      eat(SB_EQ);
      actualType = compileType();
      
      typeObj->typeAttrs->actualType = actualType;
      declareObject(typeObj);
      
      eat(SB_SEMICOLON);
    } while (lookAhead->tokenType == TK_IDENT);

    compileBlock3();
  } 
  else compileBlock3();
}
void compileBlock(void) {
  Object* constObj;
  ConstantValue* constValue;

  if (lookAhead->tokenType == KW_CONST) {
    eat(KW_CONST);

    do {
      eat(TK_IDENT);
      // TODO: Check if a constant identifier is fresh in the block
      checkFreshIdent(currentToken->string);
      // Create a constant object
      constObj = createConstantObject(currentToken->string);
      
      eat(SB_EQ);
      // Get the constant value
      constValue = compileConstant();
      constObj->constAttrs->value = constValue;
      // Declare the constant object 
      declareObject(constObj);
      
      eat(SB_SEMICOLON);
    } while (lookAhead->tokenType == TK_IDENT);

    compileBlock2();
  } 
  else compileBlock2();
}
void compileProcDecl(void) {
    // TODO: create and declare a procedure object//
    Object* obj=NULL;
    eat(KW_PROCEDURE);
    eat(TK_IDENT);
    obj = createProcedureObject(currentToken->string);
    enterBlock(obj->procAttrs->scope);

    compileParams();
    eat(SB_SEMICOLON);
    compileBlock();
    eat(SB_SEMICOLON);
    exitBlock();

    declareObject(obj);
}
Beispiel #12
0
void compileParam(void) {
  Object* param;
  Type* type;
  enum ParamKind paramKind = PARAM_VALUE;

  if (lookAhead->tokenType == KW_VAR) {
    paramKind = PARAM_REFERENCE;
    eat(KW_VAR);
  }

  eat(TK_IDENT);
  checkFreshIdent(currentToken->string);
  param = createParameterObject(currentToken->string, paramKind);
  eat(SB_COLON);
  type = compileBasicType();
  param->paramAttrs->type = type;
  declareObject(param);
}
void compileBlock(void) {
    // TODO: create and declare constant objects#
    Object * obj = NULL;
    if (lookAhead->tokenType == KW_CONST) {
        eat(KW_CONST);

        do {
            eat(TK_IDENT);
            obj = createConstantObject(currentToken->string);

            eat(SB_EQ);
            obj->constAttrs->value = compileConstant();
            eat(SB_SEMICOLON);
            declareObject(obj);
        } while (lookAhead->tokenType == TK_IDENT);

        compileBlock2();
    }
    else compileBlock2();
}
void compileProcDecl(void) {
  Object* procObj;

  eat(KW_PROCEDURE);
  eat(TK_IDENT);

  checkFreshIdent(currentToken->string);
  procObj = createProcedureObject(currentToken->string);
  declareObject(procObj);

  enterBlock(procObj->procAttrs->scope);

  compileParams();

  eat(SB_SEMICOLON);
  compileBlock();
  eat(SB_SEMICOLON);

  exitBlock();
}
void compileBlock3(void) {
    // TODO: create and declare variable objects#
    Object* obj = NULL;
    if (lookAhead->tokenType == KW_VAR) {
        eat(KW_VAR);

        do {
            eat(TK_IDENT);
            obj = createVariableObject(currentToken->string);

            eat(SB_COLON);
            obj->varAttrs->type = compileType();

            eat(SB_SEMICOLON);
            declareObject(obj);
        } while (lookAhead->tokenType == TK_IDENT);

        compileBlock4();
    }
    else compileBlock4();
}
void compileBlock2(void) {
    // TODO: create and declare type objects#
    Object* obj = NULL;
    if (lookAhead->tokenType == KW_TYPE) {
        eat(KW_TYPE);

        do {
            eat(TK_IDENT);
            obj = createTypeObject(currentToken->string);

            eat(SB_EQ);
            obj->typeAttrs->actualType = compileType();
            eat(SB_SEMICOLON);

            declareObject(obj);
        } while (lookAhead->tokenType == TK_IDENT);

        compileBlock3();
    }
    else compileBlock3();
}
void compileFuncDecl(void) {
    // TODO: create and declare a function object#
    Object* obj=NULL;

    eat(KW_FUNCTION);
    eat(TK_IDENT);
    obj = createFunctionObject(currentToken->string);
    enterBlock(obj->funcAttrs->scope);

    compileParams();
    eat(SB_COLON);

    obj->funcAttrs->returnType = compileBasicType();
    eat(SB_SEMICOLON);

    compileBlock();
    eat(SB_SEMICOLON);
    exitBlock();

    declareObject(obj);
}
void compileProcDecl(void) {
  Object* procObj;

  eat(KW_PROCEDURE);
  eat(TK_IDENT);
  // TODO: Check if a procedure identifier is fresh in the block
  checkFreshIdent(currentToken->string);
  // create a procedure object
  procObj = createProcedureObject(currentToken->string);
  // declare the procedure object
  declareObject(procObj);
  // enter the procedure's block
  enterBlock(procObj->procAttrs->scope);
  // parse the procedure's parameters
  compileParams();

  eat(SB_SEMICOLON);
  compileBlock();
  eat(SB_SEMICOLON);
  // exit the block
  exitBlock();
}
Beispiel #19
0
void initSymTab(void) {
  Object* param;

  symtab = (SymTab*) malloc(sizeof(SymTab));
  symtab->globalObjectList = NULL;
  symtab->program = NULL;
  symtab->currentScope = NULL;
  
  readcFunction = createFunctionObject("READC");
  declareObject(readcFunction);
  readcFunction->funcAttrs->returnType = makeCharType();

  readiFunction = createFunctionObject("READI");
  declareObject(readiFunction);
  readiFunction->funcAttrs->returnType = makeIntType();


  writeiProcedure = createProcedureObject("WRITEI");
  declareObject(writeiProcedure);
  enterBlock(writeiProcedure->procAttrs->scope);
    param = createParameterObject("i", PARAM_VALUE);
    param->paramAttrs->type = makeIntType();
    declareObject(param);
  exitBlock();

  writecProcedure = createProcedureObject("WRITEC");
  declareObject(writecProcedure);
  enterBlock(writecProcedure->procAttrs->scope);
    param = createParameterObject("ch", PARAM_VALUE);
    param->paramAttrs->type = makeCharType();
    declareObject(param);
  exitBlock();

  writelnProcedure = createProcedureObject("WRITELN");
  declareObject(writelnProcedure);

  intType = makeIntType();
  charType = makeCharType();
}
int main() {
	Object* obj;

	initSymTab();

	obj = createProgramObject("PRG");
	enterBlock(obj->progAttrs->scope);

	obj = createConstantObject("c1");
	obj->constAttrs->value = makeIntConstant(10);
	declareObject(obj);

	obj = createConstantObject("c2");
	obj->constAttrs->value = makeCharConstant('a');
	declareObject(obj);

	obj = createTypeObject("t1");
	obj->typeAttrs->actualType = makeArrayType(10, makeIntType());
	declareObject(obj);

	obj = createVariableObject("v1");
	obj->varAttrs->type = makeIntType();
	declareObject(obj);

	obj = createVariableObject("v2");
	obj->varAttrs->type = makeArrayType(10, makeArrayType(10, makeIntType()));
	declareObject(obj);

	obj = createFunctionObject("f");
	obj->funcAttrs->returnType = makeIntType();
	declareObject(obj);

	enterBlock(obj->funcAttrs->scope);

	obj = createParameterObject("p1", PARAM_VALUE, symtab->currentScope->owner);
	obj->paramAttrs->type = makeIntType();
	declareObject(obj);

	obj = createParameterObject("p2", PARAM_REFERENCE, symtab->currentScope->owner);
	obj->paramAttrs->type = makeCharType();
	declareObject(obj);

	exitBlock();

	obj = createProcedureObject("p");
	declareObject(obj);

	enterBlock(obj->procAttrs->scope);

	obj = createParameterObject("v1", PARAM_VALUE, symtab->currentScope->owner);
	obj->paramAttrs->type = makeIntType();
	declareObject(obj);

	obj = createConstantObject("c1");
	obj->constAttrs->value = makeCharConstant('a');
	declareObject(obj);

	obj = createConstantObject("c3");
	obj->constAttrs->value = makeIntConstant(10);
	declareObject(obj);

	obj = createTypeObject("t1");
	obj->typeAttrs->actualType = makeIntType();
	declareObject(obj);

	obj = createTypeObject("t2");
	obj->typeAttrs->actualType = makeArrayType(10, makeIntType());
	declareObject(obj);

	obj = createVariableObject("v2");
	obj->varAttrs->type = makeArrayType(10, makeIntType());
	declareObject(obj);

	obj = createVariableObject("v3");
	obj->varAttrs->type = makeCharType();
	declareObject(obj);

	exitBlock();


	exitBlock();
	printObject(symtab->program, 0);
	cleanSymTab();

	return 0;
}