%{
/*
*	Ovo je resenje treceg zadatka i to delova a, b, i c
* 	Deo d se radi rutinski. 
*/

#include <cstdio>
#include <string>
#include <map>
using namespace std;

#define yyerror printf


extern int yylex();
void print_base(unsigned x, int b);

map<string, unsigned> int_vars;
%}

%union
{
	unsigned int_attr;
	string*  str_attr;
}

%left '|'
%left '&'
%left LSHIFT RSHIFT
%left '+' '-'
%left '*' '/'
%left '~'
%left UMINUS

%type <int_attr> expr
%token PRINT 
%token <int_attr> INT_CONST
%token <str_attr> INT_ID VEC_ID

%%

statements : statements statement
	| statement
	;

statement : PRINT '('	expr ',' INT_CONST  ')' ';'
	{
		print_base($3, $5);
		putchar('\n');
	}
	|
	PRINT '(' expr ')' ';'
	{
		print_base($3, 10);
		putchar('\n');
	}
	| INT_ID '=' expr ';'
	{
		int_vars[*$1] = $3;
		delete $1;
	}
	;

expr : INT_CONST
	{	$$ = $1;	}
	|
	INT_ID
	{	
		$$ = int_vars[*$1];
		delete $1;
	}
	| expr '+' expr
	{	$$ = $1 + $3;	}
	| expr '-' expr
	{	$$ = $1 - $3;	}
	| expr '*' expr
	{	$$ = $1 * $3;	}
	| expr '/' expr
	{	$$ = $1 / $3;	}
	| '-' expr %prec UMINUS
	{	$$ = -$2;	}
	| expr '|' expr
	{	$$ = $1 | $3;	}
	| expr '&' expr
	{	$$ = $1 & $3;	}
	| expr LSHIFT expr
	{	$$ = $1 << $3;	}
	| expr RSHIFT expr
	{	$$ = $1 >> $3;	}
	| '~' expr
	{	$$ = ~$2;	}
	| '(' expr ')'
	{	$$ = $2; 	}
	;
%%

void print_base(unsigned x, int b)
{
	if (x/b)
		print_base(x/b, b);

	if (x%b < 10)
		putchar(x%b + '0');
	else
		putchar(x%b-10 + 'A');
}

main()
{
	yyparse();
}
