/* Code of Figure 4.12, pages 105-107 from
   Kenneth C. Louden, Programming Languages
   Principles and Practice 2nd Edition
   Copyright (C) Brooks-Cole/ITP, 2003
*/
/* 
   Modified by B.-M. Chang 2012 for Interpreter of Lang S
*/

#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include "global.h"   

int token; /* holds the current input token for the parse */

/* declarations to allow arbitrary recursion */
void stmt(void); 
void matchstmt(void); 
void command(void);
int expr(void);
int term(void);
int factor(void);
int number(void);
int digit(void);

void error(void)
{ 
  printf("parse error: line %d : %d\n", lineno, token);
  exit(1);
}

void match(int c) 
{ 
  if (token == c) 
     token = getToken();
  else error();
}

void stmt(void)
{  
   int loc, result, whilestart;

   switch(token) 
   {
	case ID:  	// stmt -> id = expr
		loc = tokenval; 
		match(ID); 
		if (token == '=') {
			match('=');
			result = expr( ); 
			symtable[loc].val = result; 
		}
		break;

	case '(':	// stmt --> '(' stmt {';' stmt} ')'
		match('(');






		break;

	case IF:	// stmt -> 'if' expr 'then' stmt 'end'
			        |  'if' expr 'then' stmt 'else' stmt
		match(IF);







		matchstmt(); // expr °ªÀÌ falseÀÏ ¶§ then ºÎºÐ stmt °Ç³Ê¶Ù±â 

		break;

	case WHILE:	// stmt --> 'while' expr 'do' stmt 
		whilestart = pc; // while ½ÃÀÛÀ§Ä¡ ±â¾ï
		match(WHILE);
		









		break;

	case READ:	// stmt -> 'read' id
		match(READ);






		break;

	case PRINT: 	// stmt -> 'print' expr 
		match(PRINT);







		break;

	case LET: // HW #4: stmt -> 'let' type id = expr {',' type id = expr} 'in' stmt {';' stmt} 'end'
		match(LET);







		break;
   }
}

void matchstmt(void)
{  int loc, result, whilestart;
   switch(token) 
   {
	case ID: loc = tokenval; 
		match(ID); 
		if (token == '=') {
			match('=');
			expr( ); 
		}
		break;

	case '(':
		match('(');
		matchstmt();
		while(token == ';') {
			match(';');
			matchstmt();
		}
		if (token == ')') 
			match(')');
		break;

	case IF:
		match(IF);
		expr();
		matchstmt();
		match(ELSE); 
		matchstmt();
		break;

	case WHILE:
		match(WHILE);
		expr();
		match(DO);
		matchstmt();
		break;

	case READ:
		match(READ);
		match(ID);
		break;

	case PRINT: 
		match(PRINT); 
		expr();
		break;
   }
}


int expr(void)
{ int value1, value2, result;

  if (token == '!') { 		
			// expr -> '!' expr 
	

	
		
    return result;
  }
			// expr -> TRUE

			// expr -> FALSE

  result = aexpr();

  switch(token) 
  {
	case '=' : 		// expr -> aexpr '==' aexpr
		match('=');
		match('=');
		value1 = result;
		value2 = aexpr();
		if (value1 == value2)
			result = 1;
		else result = 0;
		break;
	case '!' :		// expr -> aexpr '!=' aexpr 





		break;

	case '>' :		// expr -> aexpr '>' aexpr 





		break;

	case '<' :  		// expr -> aexpr '<' aexpr





		break;
  }

  return result;

}

int aexpr(void)
/* aexpr -> term { '+' term } */
{ int value1, value2, result;

  result = term();
  while (token == '+' || token == '-')	// aexpr -> term {'+' term | '-' term}
  { 
	if (token == '+') {
	   match('+');
	   result += term();
	} else {
	   match('-');
	   result -= term();
	}
  }

  return result;
}

int term(void)
/* term -> factor { '*' factor } */
{ int result = factor();
  while (token == '*')
  { 
	match('*');
    result *= factor();
  }
  return result;
}

int factor(void)
/* factor -> '(' expr ')' | number | id */
{ int loc, result;
  if (token == '(')
  { match('(');
    result = expr();
    match(')');
  }
  else if (token == NUM)  // number
	{
	  result = tokenval;
	  token = getToken();
	}
  else if (token == ID || token == INT || token == BOOL)  // variable
	{ 
          loc = tokenval;
	  result = symtable[loc].val;
	  token = getToken();
	}

  return result;
}

void parse(void)
{ 
  token = getToken(); 
  stmt(); 	
}

int main()
{ 
  init();  // initialize 
  parse();
  return 0;
}
