Ejemplo n.º 1
0
static void swap() {
    int left_var = variable(), right_var = variable();
    int reg_one = next_register(), reg_two = next_register();
    CodeGen(LOAD, reg_one, left_var, EMPTY_FIELD);
    CodeGen(LOAD, reg_two, right_var, EMPTY_FIELD);
    CodeGen(STORE, left_var, reg_two, EMPTY_FIELD);
    CodeGen(STORE, right_var, reg_one, EMPTY_FIELD);
}
Ejemplo n.º 2
0
static int expr()
{
	int reg, left_reg, right_reg;

	switch (token) {
	case '+':
		next_token();
		left_reg = expr();
		right_reg = expr();
		reg = next_register();
		CodeGen(ADD, reg, left_reg, right_reg);
		return reg;
	case '*':
		next_token();
		left_reg = expr();
		right_reg = expr();
		reg = next_register();
		CodeGen(MUL, reg, left_reg, right_reg);
		return reg;
	case '-':
		next_token();
		left_reg = expr();
		right_reg = expr();
		reg = next_register();
		CodeGen(SUB, reg, left_reg, right_reg);
		return reg;

	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		return digit();
    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
        return variable();

	default:
		ERROR("Symbol %c unknown\n", token);
		exit(EXIT_FAILURE);
	}
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
	const char *outfilename = "tinyL.out";
	char *input;
	FILE *infile;

	printf("------------------------------------------------\n");
	printf("      Compiler for tinyL\n          Fall 2015\n");
	printf("------------------------------------------------\n");
	if (argc != 2) {
		ERROR("Use of command:\n  compile <tinyL file>\n");
		exit(EXIT_FAILURE);
	}
	infile = fopen(argv[1], "r");
	if (!infile) {
		ERROR("Cannot open input file \"%s\"\n", argv[1]);
		exit(EXIT_FAILURE);
	}
	outfile = fopen(outfilename, "w");
	if (!outfile) {
		ERROR("Cannot open output file \"%s\"\n", outfilename);
		exit(EXIT_FAILURE);
	}
	input = read_input(infile);
	buffer = input;

	CodeGen(LOADI, 1024, 0, EMPTY_FIELD); /* set base register to 1024 */
	program();
	printf("\nCode written to file \"%s\".\n\n", outfilename);
	free(input);
	fclose(infile);
	fclose(outfile);
	return EXIT_SUCCESS;
}
Ejemplo n.º 4
0
static void read()
{
    next_token();
	if (!is_identifier(token)) {
		ERROR("Expected identifier\n");
        exit(EXIT_FAILURE);
    }
    CodeGen(READ, token, EMPTY_FIELD, EMPTY_FIELD);
    next_token();
}
Ejemplo n.º 5
0
static void assign() {
    int var = variable();
    if (token == '=') {
        next_token();
        int reg = expr();
        CodeGen(STORE, var, reg, EMPTY_FIELD);
    } else {
        ERROR("Syntax Error: In assignment, expected '='.\n");
    }
}
Ejemplo n.º 6
0
static void print()
{
	switch (token) 
	{
		case '!':
			next_token();
			CodeGen(WRITE, token, EMPTY_FIELD, EMPTY_FIELD);
			next_token();
			return ;
	}
}
Ejemplo n.º 7
0
static void assign()
{
	char id;
	int right_reg;
	id = token;
	next_token();
	next_token();
	right_reg = expr();
	CodeGen(STORE, id, right_reg, EMPTY_FIELD);
	return;
}
Ejemplo n.º 8
0
static void read()
{
	switch (token) 
	{
		case '?':
			next_token();
			CodeGen(READ, token, EMPTY_FIELD, EMPTY_FIELD);
			next_token();
			return;
	}
}
Ejemplo n.º 9
0
static int variable()  /* only called for R-values */
{
        int reg;
        if(!is_identifier(token)){
            ERROR("Expected identifier\n");
            exit(EXIT_FAILURE);
        }
        reg = next_register();
        CodeGen(LOAD, reg, token, EMPTY_FIELD);
        next_token();
        return reg;
}
Ejemplo n.º 10
0
static int variable()
{
	int reg;

	if (!is_identifier(token)) {
		ERROR("Expected identifier\n");
		exit(EXIT_FAILURE);
	}
	reg = next_register();
	CodeGen(LOADAI, 0, (token-'a')*4, reg); /* token - 'a' is offset of varible, *4 for byte address */
	next_token();
	return reg;
}
Ejemplo n.º 11
0
static int digit()
{
	int reg;

	if (!is_digit(token)) {
		ERROR("Expected digit\n");
		exit(EXIT_FAILURE);
	}
	reg = next_register();
	CodeGen(LOADI, to_digit(token), reg, EMPTY_FIELD);
	next_token();
	return reg;
}
Ejemplo n.º 12
0
static void print()
{
    next_token();
    if(is_identifier(token)){
        char variable = token;
        CodeGen(OUTPUTAI, variable,EMPTY_FIELD,EMPTY_FIELD);
        next_token();
    }else {
        ERROR("Expected a variable");
         exit(EXIT_FAILURE);
    }
    /* YOUR CODE GOES HERE */
}
Ejemplo n.º 13
0
static void print()  /* variables are handled explicitly without recursive call */
{
	if (token != '!') {
		ERROR("Expected print statement\n");
		exit(EXIT_FAILURE);
	}
	next_token();
	if (!is_identifier(token)) {
		ERROR("Expected identifier\n");
		exit(EXIT_FAILURE);
	}
	CodeGen(WRITE, token, EMPTY_FIELD, EMPTY_FIELD);
	next_token();
}
Ejemplo n.º 14
0
static void print()
{
	if(token != '!'){
		ERROR("Expected '!', got %c\n", token);
		exit(EXIT_FAILURE);
	}
	next_token();
	if(!is_identifier(token)){
		ERROR("Expected identifier, got %c\n", token);
		exit(EXIT_FAILURE);
	}
	int offset = (token-'a')*4;
	next_token();
	CodeGen(OUTPUTAI, 0, offset, EMPTY_FIELD);
}
Ejemplo n.º 15
0
static void assign()
{
	int reg;
	if(!is_identifier(token)){
		ERROR("Identifier expected, got %c\n", token);
		exit(EXIT_FAILURE);
	}
	int offset = (token-'a')*4;
	next_token();
	if(token != '='){
		ERROR("Expected '=', got %c\n", token);
		exit(EXIT_FAILURE);
	}
	next_token();
	reg = expr();
	CodeGen(STOREAI, reg, 0, offset);
}
Ejemplo n.º 16
0
static void assign()
{
	char ident;
        int reg;

	if (!is_identifier(token)) {
		ERROR("Expected identifier\n");
		exit(EXIT_FAILURE);
	}
	ident = token;
	next_token();
	if (token != '=') {
		ERROR("Expected equal sign for assignment statement\n");
		exit(EXIT_FAILURE);
	};
	next_token();
        reg = expr();

	CodeGen(STORE, ident, reg, EMPTY_FIELD);
}
Ejemplo n.º 17
0
static void assign()
{
    

    
        char variable = token;
        next_token();
        if(token == '=') {
            next_token();
            int x = expr();
            CodeGen(STOREAI, variable, x, EMPTY_FIELD);
            next_token();
        }else{
            ERROR("Expected '=' ");
             exit(EXIT_FAILURE);
        }
    
    
    /* YOUR CODE GOES HERE */
}
Ejemplo n.º 18
0
int CodeGen(NODPTR ptr)
{
	int t1, t2, t;	
	switch(ptr->NodeType)
	{
		case CONST:
					t = getFreeReg();
					fprintf(fp, "MOV R%d %d\n", t, ptr->value);
					return t;
					break;
		case VARIABLE:
					t = getFreeReg();
					fprintf(fp, "MOV R%d [%d]\n", t, ptr->stptr->binding);
					return t;
					break;
		case RD:
					t = getFreeReg();
					fprintf(fp,"IN R%d\n", t);
					fprintf(fp, "MOV [%d] R%d\n", ptr->Lptr->stptr->binding, t);
					reg[t] = 0;
					return 0;
					break;
		//Recursive cases.
		case WE:
					t2 = CodeGen(ptr->Lptr);
					t1 = getFreeReg();
					fprintf(fp, "MOV R%d R%d \n", t1, t2);
					fprintf(fp,"OUT R%d\n", t1);
					reg[t1] = 0;
					reg[t2] = 0;
					return 0;
					break;
		case PLUS:
					t1 = CodeGen(ptr->Rptr);
					t2 = CodeGen(ptr->Lptr);
					fprintf(fp, "ADD R%d R%d\n", t2, t1);
					reg[t1] = 0;
					return t2;
					break;
		case MINUS:
					t1 = CodeGen(ptr->Rptr);
					t2 = CodeGen(ptr->Lptr);
					fprintf(fp, "SUB R%d R%d\n", t2, t1);
					reg[t1] = 0;
					return t2;
					break;
		case MUL:
					t1 = CodeGen(ptr->Rptr);
					t2 = CodeGen(ptr->Lptr);
					fprintf(fp, "MUL R%d R%d\n", t2, t1);
					reg[t1] = 0;
					return t2;
					break;
		case DIV:
					t1 = CodeGen(ptr->Rptr);
					t2 = CodeGen(ptr->Lptr);
					fprintf(fp, "DIV R%d R%d\n", t2, t1);
					reg[t1] = 0;
					return t2;
					break;
		case SEQ:
					CodeGen(ptr->Lptr);
					if(ptr->Rptr)
						CodeGen(ptr->Rptr);
					return 0;
					break;
		case EQUAL:
					t1 = CodeGen(ptr->Rptr);
					fprintf(fp, "MOV [%d] R%d\n", ptr->Lptr->stptr->binding, t1);
					return 0;
					break;
	}
}
Ejemplo n.º 19
0
int CodeGen(tnode* t)
{
	int r,r1,r2;
	int value;
	int loc,l1,l2;
	//r is the root of AST
	//returntype of CodeGen is int that is it returns the register Number
	switch(t->NODETYPE)
	{

		case NUM:
			value=t->val;
			r=getReg();
			fprintf(fp,"MOV R%d, %d\n",r,value);
			return r;
			break;

		case ID:
			loc=t->var-'a';
			r=getReg();
			fprintf(fp, "MOV R%d, [%d]\n",r,loc);
			return r;
			break;

		case PLUS:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "ADD R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case MINUS:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "SUB R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case MUL:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "MUL R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case DIV:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "DIV R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case MOD:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "MOD R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case LT:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "LT R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case GT:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "GT R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case EQ:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "EQ R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case EQUALS:
			r1=getBinding(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "MOV [R%d], R%d\n",r1,r2);
			freeReg();
			freeReg();
			return 0;
			break;

		case READ:
			r=getBinding(t->left);
			r1=getReg();
			fprintf(fp, "IN R%d\n",r1);
			fprintf(fp, "MOV [R%d], R%d\n",r,r1);
			freeReg();
			freeReg();
			return 0;
			break;

		case WRITE:
			r=CodeGen(t->left);
			fprintf(fp, "OUT R%d\n",r);
			freeReg();
			return 0;
			break;
		case IF:
				l1=getLabel();
				r=CodeGen(t->left);
				r1=getReg();
				fprintf(fp, "MOV R%d, 0\n",r1);
				fprintf(fp, "NE R%d, R%d\n",r,r1);
				fprintf(fp, "JZ R%d, L%d\n",r,l1);
				freeReg();
				freeReg();
				CodeGen(t->right);
				fprintf(fp, "L%d:\n",l1);
				return 0;
				break;

		case WHILE:
			{
				l1=getLabel();
				l2=getLabel();
				fprintf(fp, "L%d:\n",l1);
				r=CodeGen(t->left);
				r1=getReg();
				fprintf(fp, "MOV R%d, 0\n",r1);
				fprintf(fp, "NE R%d, R%d\n",r,r1);
				fprintf(fp, "JZ R%d, L%d\n",r,l2);
				freeReg();
				freeReg();
				CodeGen(t->right);
				fprintf(fp, "JMP L%d\n",l1);
				fprintf(fp, "L%d:\n",l2);
				return 0;
			}
				break;

		case CONNECT:
			CodeGen(t->left);
			CodeGen(t->right);
			return 0;
			break;
	}


}
Ejemplo n.º 20
0
int CodeGen(NODPTR ptr)
{
	int t1, t2, t, b;	
	switch(ptr->NodeType)
	{
		case CONST:
				t = regcount++;
				fprintf(Fp, "MOV R%d %d\t//\tMoving constant to a register.\n",
							 t, ptr->value);
				return t;
				break;
		case TRUE:
				t = regcount++;
				fprintf(Fp, "MOV R%d %d\t//\tMoving true(1) to a register.\n",
							 t, ptr->value);
				return t;
				break;
		case FALSE:
				t = regcount++;
				fprintf(Fp, "MOV R%d %d\t//\tMoving false(0) to a register.\n",
							 t, ptr->value);
				return t;
				break;
		case VARIABLE:		
				
				t1 = regcount++;
				if(ptr->Lstptr)
				{
					b = ptr->Lstptr->binding;
					t2 = regcount++;	// Need another register for storing base pointer.
				
					fprintf(Fp, "MOV R%d BP\t//\tMoving base pointer to a register.\n", t2);
					fprintf(Fp, "MOV R%d %d\t//\tStoring the relative address of the variable.\n",
							 t1, b);
					fprintf(Fp, "ADD R%d R%d\t//\tAdding it with base pointer for absol. address\n",
							  t1, t2);
					fprintf(Fp, "MOV R%d [R%d]\t//\tMoving variable contents to register.\n",
							 t1, t1);
					regcount--;
				}
				else
				{
					b = ptr->Gstptr->binding;
					fprintf(Fp, "MOV R%d %d\t//\tThe variable is global,so absolute address is used",
							 t1, b);
					fprintf(Fp, "MOV R%d [R%d]\t//\tMoving variable contents to register.\n",
							 t1, t1);
				}

				return t1;
				break;

		//Recursive cases.
		case ARRAY:	 	
				t1 = CodeGen(ptr->Rptr);
				t = regcount++;
				b = ptr->Lptr->Gstptr->binding;
				fprintf(Fp, "MOV R%d %d\t//\tMoving binding field.\n", t, b);
				fprintf(Fp, "ADD R%d R%d\t//\tAdding binding with the offset.\n", t1, t);
				if(ArrFlag == 1)
					fprintf(Fp, "MOV R%d [R%d]\t//\t...and loading it onto a register.\n",
							t1,t1);
				regcount--;
				/*If ArrayFlag == 1 
					t1 will contain the value
				  otherwise
				  	t1 will contain the absolute address */ 
				return t1;
				break;
		case RD:
				t = regcount++;
				fprintf(Fp,"IN R%d\t\t//\tReading from input.\n", t);
				
				if(ptr->Lptr->Lstptr)
					b = ptr->Lptr->Lstptr->binding;
				else
					b = ptr->Lptr->Gstptr->binding;
					
				if(ptr->Lptr->NodeType == VARIABLE)
				   fprintf(Fp, "MOV [%d] R%d\t//\tMoving the read content to variable.\n",
			 	                  b, t);
				else
				{
					// Done inorder to generate code to obtain array binding field.
					ArrFlag = 0;
					t1 = CodeGen(ptr->Lptr);
					ArrFlag = 1;
					fprintf(Fp, "MOV [R%d] R%d\t//\tMoving the read content to an array.\n",
								t1, t);
					regcount--;
				}
				regcount--;
				break;
		case WE:
				t = CodeGen(ptr->Lptr);
				fprintf(Fp,"OUT R%d\t\t//\tOutput the register content\n", t);
				regcount--;
				return 0;
				break;
		case PLUS:
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "ADD R%d R%d\t//\tPLUS\n", t1, t2);
				regcount--;
				return t1;
				break;
		case MINUS:
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "SUB R%d R%d\t//\tMINUS\n", t1, t2);
				regcount--;
				return t1;
				break;
		case MUL:
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "MUL R%d R%d\t//\tMUL\n", t1, t2);
				regcount--;
				return t1;
				break;
		case DIV:
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "DIV R%d R%d\t//\tDIV\n", t1, t2);
				regcount--;
				return t1;
				break;
		case SEQ:
				CodeGen(ptr->Lptr);
				if(ptr->Rptr)
					CodeGen(ptr->Rptr);
				return 0;
				break;
		case FUNC:
                                fprintf(Fp, "PUSH R0\n");        // 1. Push dummy value for storing return value.
			        for(t = 0; t < 8; t++)
				  fprintf(Fp, "PUSH R%d\n", t);  // 2.Pushing machine status. 
				
				fprintf(Fp, "PUSH BP\n");	// 3. Storing caller's BP
				
				NODPTR tmp = ptr->list;
				while(tmp)
				{
					t = CodeGen(tmp);	// 4.Pushing the parameters.
					fprintf(Fp, "PUSH R%d\n", t);
					tmp = tmp->next;
				}
				fprintf("CALL F%d\n", ptr->Lptr->Gstptr->binding); // 5.Calling the function.
				// After function call.
				tmp = ptr->list;
				while(tmp) // 1. poping parameters
				{
					fprintf(Fp, "POP R0\n");
					tmp = tmp->next;
				}
				
				fprintf(Fp, "POP BP\n"); //2 .Restoring BP
				for(t = 7; t >= 0; t--)
				  fprintf(Fp, "POP R%d\n", t);  // 2.Restoring machine status.
				t1 = regcount++;
				
				fprintf("MOV R%d [SP]\n", t1);//3. Copying back the return value.
				return t1;
				  
				break;
		case EQUAL:		
				t1 = CodeGen(ptr->Rptr);
				if(ptr->Lptr->Lstptr)
					b = ptr->Lptr->Lstptr->binding;
				else
					b = ptr->Lptr->Gstptr->binding;
					
				if(ptr->Lptr->NodeType == VARIABLE)
					fprintf(Fp, "MOV [%d] R%d\t//\tAssigning register contents to variable\n",
						 b, t1);
				else
				{
					// Done inorder to generate code to obtain array binding field.
					ArrFlag = 0;
					t2 = CodeGen(ptr->Lptr);
					ArrFlag = 1;
					fprintf(Fp, "MOV [R%d] R%d\t//\tAssigning register contents to array\n",
							 t2, t1);
					regcount--;
				}
				regcount--;
				return 0;
				break;

		case GT:
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "GT R%d R%d\t//\tGreater than.\n", t1, t2);
				regcount--;
				return t1;
				break;
		case LT:		
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "LT R%d R%d\t//\tLesser than.\n", t1, t2);
				regcount--;
				return t1;
				break;
		case GTE:		
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "GE R%d R%d\t//\tGreater than or equal.\n", t1, t2);
				regcount--;
				return t1;
				break;

		case LTE:		
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "LE R%d R%d\t//\tLesser than or equal.\n", t1, t2);
				regcount--;
				return t1;
				break;
					
		case ISEQUAL:		
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "EQ R%d R%d\t//\tIs equal.\n", t1, t2);
				regcount--;
				return t1;
				break;

		case NE:		
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "NE R%d R%d\t//\tIs not equal.\n", t1, t2);
				regcount--;
				return t1;
				break;

		case AND:		
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "MUL R%d R%d\t//\tAND operation.\n", t1, t2);
				regcount--;
				return t1;
				break;
					
		case OR:		
				t1 = CodeGen(ptr->Lptr);
				t2 = CodeGen(ptr->Rptr);
				fprintf(Fp, "ADD R%d R%d\t//\tOR operation.\n", t1, t2);
				fprintf(Fp, "MOV R%d %d\t//\tOR operation.\n", t2, 0);
				fprintf(Fp, "NE R%d R%d\t//\tOR operation.\n", t1, t2);
				regcount--;
				return t1;
				break;
					
		case NOT:		
				t = regcount++;
				t1 = CodeGen(ptr->Lptr);
				fprintf(Fp, "MOV R%d %d\t//\tNOT operation.\n", t, 1);
				fprintf(Fp, "SUB R%d R%d\t//\tNOT operation.\n", t, t1);
				regcount--;
				return t;
				break;

		case IF_THEN:	
				t1 = Branching_Label++;
				t = CodeGen(ptr->Lptr);
				fprintf(Fp, "JZ R%d L%d\t// If then\n", t, t1);
				regcount--;		// Freeing the register.
				CodeGen(ptr->Rptr);
				fprintf(Fp, "L%d:\t\t// Endif\n",t1);
				return 0;
				break;
		case IF_THEN_ELSE:
				t = CodeGen(ptr->Lptr);
				// Two labels are needed for if else
				t1 = Branching_Label++;
				t2 = Branching_Label++;
				fprintf(Fp, "JZ R%d L%d\t// If then else\n", t, t1);
				regcount--;		// Freeing the register.
				CodeGen(ptr->Mptr);
				fprintf(Fp, "JMP L%d\n", t2);
				fprintf(Fp, "L%d:\t\t// ...else\n", t1);
				CodeGen(ptr->Rptr);
				fprintf(Fp, "L%d:\t\t// End if else\n",t2);
				return 0;
				break;
		case DO_WHILE:
				// Two labels are needed for while do
				t1 = Branching_Label++;
				t2 = Branching_Label++;
				fprintf(Fp, "L%d:\n",t1);
				t = CodeGen(ptr->Lptr);
				fprintf(Fp, "JZ R%d L%d\t// While do\n", t, t2);
				regcount--;		// Freeing the register.
				CodeGen(ptr->Rptr);
				fprintf(Fp, "JMP L%d\t\t// Endwhile\n", t1);
				fprintf(Fp, "L%d:\n",t2);
				return 0;					
				break;
	}
}
Ejemplo n.º 21
0
static void print() {
    int var = variable();
    CodeGen(WRITE, var, EMPTY_FIELD, EMPTY_FIELD);
}
Ejemplo n.º 22
0
static void read() {
    int var = variable();
    CodeGen(READ, var, EMPTY_FIELD, EMPTY_FIELD);
}