Example #1
0
/// Present a simple challenge consisting of two random digits to 
/// add. The user tries to enter the last digit of their sum.
void askSum(MorseToken) {
   uint8_t a(getDigitByWeight());
   uint8_t b(getDigitByWeight());
   char buffer[3] = { char(a + '0'), char(b + '0'), 0 };
   txString(buffer);
   pushSymbolStack(MorseToken(buffer[0], MorseToken::Char));
   pushSymbolStack(MorseToken(buffer[1], MorseToken::Char));
   saveActions();
   for (size_t i('0'); i <= '9' ; ++i) {
      assignAction(MorseToken(i, MorseToken::Char), gradeRestore);
   }
}
Example #2
0
/// This is a little harder than askNext in that the extra letters can
/// be distracting, but it is a little easier because there's more
/// context. I expect that for beginners, the former is easier, but for
/// intermediates, the latter is good practice.
void askNextAlfa(MorseToken) {
   uint8_t a(random(26));
   txAlfaBravoCharlie(MorseToken(a + 'A', MorseToken::Char));
   uint8_t b((a + 1) % 26);
   pushSymbolStack(MorseToken(b + 'A', MorseToken::Char));
   assignAction(MorseToken('I', MorseToken::Char), gradeNext);
   saveActions();
   for (size_t i('A'); i <= 'Z' ; ++i) {
      assignAction(MorseToken(i, MorseToken::Char), push1RestoreAll);
   }
}
Example #3
0
/// Prompt with a random letter of the alphabet. The user enters the
/// letter then enters I to get graded.
void askNext(MorseToken) {
   uint8_t a(random(26));
   char buffer[3] = { char(a + 'A'), 0 };
   txString(buffer);
   uint8_t b((a + 1) % 26);
   pushSymbolStack(MorseToken(b + 'A', MorseToken::Char));
   assignAction(MorseToken('I', MorseToken::Char), gradeNext);
   saveActions();
   for (size_t i('A'); i <= 'Z' ; ++i) {
      assignAction(MorseToken(i, MorseToken::Char), push1RestoreAll);
   }
}
Example #4
0
void gradeRestore(MorseToken answer) {
  pushSymbolStack(answer);
  gradeSum(MorseToken());
  restoreActions();
}
void semantics(ASTnode* ASTroot){
	firstMatrix=1;
	if(ASTroot==NULL){
		return;
	}
	int z,noTraverse=0;
	ASTnode *rows,*l;
	token bufToken;
	SymbolTable *tmp;
	SymbolTableEntryNode *t;
	int p=0;
	if(sflag==0){
		//first time, main function so create a symbol table for main function
		sflag=1;
		S[0]=createSymbolTable(size, NULL, "MAIN");//parentTable of Main is NULL
		symbolStack=createSymbolStack();
		pushSymbolStack(S[0],symbolStack);
		p=1;
		counter++;
		}
		
	switch(ASTroot->label){
	//Symbol Table creates only in 1, 61, 64
	//Symbol table populates in  1:functionDef,31:declarationStmt
		case 1://make a new symbol table, this would be the scope unless an END is encountered, functionDef
			InsertSymbolTable(topSymbolStack(symbolStack), ASTroot);
			S[counter]=createSymbolTable(size, topSymbolStack(symbolStack),ASTroot->array[1]->t.lexeme);
			pushSymbolStack(S[counter],symbolStack);
			InsertSymbolTableFun(topSymbolStack(symbolStack), ASTroot);//for input and output arguments of function
			p=1;
			counter++;
			break;
		case 2://ifstmt
			S[counter]=createSymbolTable(size, topSymbolStack(symbolStack),"IF");
			pushSymbolStack(S[counter],symbolStack);
			p=1;
			counter++;
			break;
		case 3: noTraverse=1;
			if(strcmp(topSymbolStack(symbolStack)->symbolTableName,ASTroot->array[0]->t.lexeme)==0){//checking for Recursion
				
				semanticError(3,ASTroot->array[0]->t);
				return;
				}
			//check for input parameter list and function signature- input and output
			tmp=topSymbolStack(symbolStack);
			 while(tmp!=NULL){
			 	z=SearchHashTable(tmp, ASTroot->array[0]->t.lexeme);
				if(z!=-1)
					break;
				else tmp=tmp->parentTable;
				}
				if(tmp==NULL){
					semanticError(1,ASTroot->t);
					break;
				}//declaration of FunId is checked here itself
				t=findSymbolTableNode(tmp->table[z].next,ASTroot->array[0]->t.lexeme);
				if(t->type.fid.outputSize!=typeCounter){
					semanticError(5,ASTroot->array[0]->t);
					break;
				}
				else{
					for(z=0; z<=t->type.fid.outputSize; z++){
						if(t->type.fid.output[z]!=type[z]){
							semanticError(5,ASTroot->array[0]->t);
							noTraverse=1;
							break;//from for
						}					
				}
					typeCounter=-1;//successfully implemented.
				}
				l=ASTroot->array[1];
				for(z=0; z<=t->type.fid.inputSize; z++){
					if(l==NULL){
						semanticError(5,ASTroot->array[0]->t);//number of output parameters
						noTraverse=1;
						break;
						}
					if(t->type.fid.input[z]!=findTypeVar(l->array[0])){
						semanticError(14,ASTroot->array[0]->t);//type Mismatch
						noTraverse=1;
						break;
					}
					l=l->array[1];					
				}
			break;
		
		case 11://else stmt
			S[counter]=createSymbolTable(size, topSymbolStack(symbolStack),"ELSE");
			pushSymbolStack(S[counter],symbolStack);
			p=1;
			counter++;
			break;	
		case 26:if(ASTroot->array[0]->label==67){
				t=getSymbolTableNode(ASTroot->array[1]);
				t->type.id.initialized=1;
			}
		case 27: break;
		case 28: break; //it should not come
		case 29: break;
		case 30: break;
		case 31://declaration stmt
			InsertSymbolTable(topSymbolStack(symbolStack), ASTroot);
			return;
			break;
		case 51://Assignment
			noTraverse=1;
			typeCounter=-1;
			if(ASTroot->array[1]->label==3){//function call statement
			
				if(ASTroot->array[0]->label==54){//single list
					if(outputCheck1(ASTroot->array[0])==0)//send leaf directly
					return;
				//1- it should already have been declared, 2-if so, then it's type should be recorded
				}
				else{
				//send l
					if(outputCheck(ASTroot->array[0])==0)
						return;
				}
				semantics(ASTroot->array[1]);
			}
			if(ASTroot->array[1]->label==60){//size stmt
				//1- check if ID is declared, 2- What is the type of ID, 3- Compare with the return type
				if(!isDeclared(ASTroot->array[1]->array[0])){
					semanticError(1,ASTroot->array[1]->array[0]->t);
					return;
				}
				z=findType(ASTroot->array[1]->array[0],0);
				if(z==57){
					if(outputCheck(ASTroot->array[0])==0){//it will populate type of LHS if declared, else returns 0
						return;
						}
					else{//declared
						if(!(typeCounter==0&&type[0]==57))
							semanticError(6,ASTroot->array[0]->t);
							return;
						}
					}
				else if(z==58){
					if(outputCheck(ASTroot->array[0])==0){//it will populate type of LHS if declared, else returns 0
						return;
						}
					else{//declared
						if(!(typeCounter==1&&type[0]==55&&type[1]==55))
							semanticError(6,ASTroot->array[0]->t);
							return;
						}
						
					}
				else {
					semanticError(8,ASTroot->array[1]->array[0]->t);//Size contains other that String and Matrix
					}
				}
			if(ASTroot->array[1]->label==37){//Arithmetic Expression
				l=ASTroot->array[0];
				z=findType(l,1);
				if(l->label==54){
					if(z==57){
						if(ASTroot->array[1]->array[1]==NULL){
							if(ASTroot->array[1]->array[0]->array[1]==NULL){
								if(findTypeVar(ASTroot->array[1]->array[0]->array[0])==57){//initialization
									StringInit(ASTroot->array[0],ASTroot->array[1]->array[0]->array[0]->t.lexeme);
									return;				
							}
							}
						}
					}
					else if(z==58){//lhs is matrix
						firstMatrix=1;
						if(ASTroot->array[1]->array[1]==NULL){
							if(ASTroot->array[1]->array[0]->array[1]==NULL){
								if((ASTroot->array[1]->array[0]->array[0]->label)==44){//initialization
									MatrixInit(ASTroot->array[0],ASTroot->array[1]->array[0]->array[0]);			
									return;
								}
							}
						}
					}
										
				}
				if(z==-1)
					break;
				typeCounter++;
				type[typeCounter]=z;
				if((z=findTypeAE(ASTroot->array[1]))!=type[typeCounter]){
					bufToken.lineNumber=l->t.lineNumber;
					semanticError(10,bufToken);
					break;
				}
				//valid Arithmetic expression
				//debug();
				t= getSymbolTableNode(ASTroot->array[0]);
				t->type.id.initialized=1;
				typeCounter=-1;
			}
			break;
		case 52://go to case 54
		case 54: if(!isDeclared(ASTroot))
					semanticError(1,ASTroot->t);
			break;	
		case 75:// AND
		case 76:// OR
		case 77:// LT
		case 78:// LE
		case 79:// EQ
		case 80:// GT
		case 81:// GE
		case 82:// NE
		case 83:// NOTbooleanExpressionSemantics(ASTnode* BE)	
			noTraverse=1;
			if(booleanExpressionSemantics(ASTroot)==0){
				semanticError(10,bufToken);
			}	
		default: break;
			
	}//end of switch
	int i;
	if(noTraverse==0){
		for( i=0; i<ASTroot->arraySize; i++){
			if(ASTroot->array[i]!=NULL){
				semantics(ASTroot->array[i]);
			}
		}
	}
	
	if(p){
		//if popping SymbolTable is a function, then check if it's output parameter are accurately initialised or not
		tmp=popSymbolStack(symbolStack);
		if(strcmp(tmp->symbolTableName,"MAIN")!=0&&strcmp(tmp->symbolTableName,"IF")!=0&&strcmp(tmp->symbolTableName,"ELSE")!=0){//it is a function
			int i;
			for(i=0; i<tmp->outputParameter; i++){
				t=outputParameterInitCheck(tmp,tmp->outputParameterLexeme[i]);
				if(t->type.id.initialized!=1)
					{
						semanticError(13,ASTroot->array[1]->t);
						break;
					}
					}
		}
		}
	
	}//end of function