diff --git a/asm b/asm/asm similarity index 100% rename from asm rename to asm/asm diff --git a/asm/asm2 b/asm/asm2 new file mode 100644 index 0000000..334dc98 --- /dev/null +++ b/asm/asm2 @@ -0,0 +1,31 @@ +AFC 0 5 +STORE 1 0 +LOAD 0 1 +STORE 0 0 +AFC 0 8 +STORE 1 0 +LOAD 0 0 +LOAD 1 1 +EQ 2 1 0 +STORE 2 2 +LOAD 0 2 +NOT 2 0 +STORE 3 2 +JMF 3 30 +AFC 0 20 +STORE 4 0 +LOAD 0 0 +LOAD 1 4 +INF 2 0 1 +STORE 2 2 +JMF 2 30 +AFC 0 2 +STORE 1 0 +LOAD 0 0 +LOAD 1 1 +ADD 0 0 1 +STORE 4 0 +LOAD 0 4 +STORE 0 0 +JMP 14 +NOP \ No newline at end of file diff --git a/asm/asm3 b/asm/asm3 new file mode 100644 index 0000000..8bc10dd --- /dev/null +++ b/asm/asm3 @@ -0,0 +1 @@ +((x"06000500"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000800"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"07000200"),(x"0C020000"),(x"08030200"),(x"10031E00"),(x"06001400"),(x"08040000"),(x"07000000"),(x"07010400"),(x"09020001"),(x"08020200"),(x"10021E00"),(x"06000200"),(x"08010000"),(x"07000000"),(x"07010100"),(x"01000001"),(x"08040000"),(x"07000400"),(x"08000000"),(x"0F0E0000"),(x"FF000000"),others => (x"ff000000")) \ No newline at end of file diff --git a/compilateur/Makefile b/compilateur/Makefile new file mode 100644 index 0000000..23c923b --- /dev/null +++ b/compilateur/Makefile @@ -0,0 +1,36 @@ +GRM=yacc.y +LEX=lex.l +BIN=out + +CC=gcc +CFLAGS=-Wall -g + +OBJ=yacc.tab.o lex.yy.o table.o operations.o blocs.o asmTable.o + +asm: $(BIN) + @touch ../tests/testFile # to prevent an error in case of deletion + ./out < ../tests/testFile + +build: $(BIN) + +%.o: %.c + $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ + +yacc.tab.c: $(GRM) + bison -d -t -v $< + +lex.yy.c: $(LEX) + flex $< + +$(BIN): $(OBJ) + $(CC) $(CFLAGS) $(CPPFLAGS) $^ -o $@ + +clean: + rm $(OBJ) yacc.tab.c yacc.tab.h lex.yy.c + +vhdl: clean asm + python3 ../cross-Compiler/cross-compiler.py + +inter: clean asm + python3 ../interpreter/graph_interpreter.py + diff --git a/compilateur/asm b/compilateur/asm new file mode 100644 index 0000000..a31cf62 --- /dev/null +++ b/compilateur/asm @@ -0,0 +1,13 @@ +AFC 1 5 +COP 0 1 +AFC 1 8 +EQ 2 0 1 +NOT 3 2 +JMF 3 13 +AFC 4 20 +INF 2 0 4 +JMF 2 13 +AFC 1 2 +ADD 4 0 1 +COP 0 4 +JMP 6 diff --git a/compilateur/asm2 b/compilateur/asm2 new file mode 100644 index 0000000..334dc98 --- /dev/null +++ b/compilateur/asm2 @@ -0,0 +1,31 @@ +AFC 0 5 +STORE 1 0 +LOAD 0 1 +STORE 0 0 +AFC 0 8 +STORE 1 0 +LOAD 0 0 +LOAD 1 1 +EQ 2 1 0 +STORE 2 2 +LOAD 0 2 +NOT 2 0 +STORE 3 2 +JMF 3 30 +AFC 0 20 +STORE 4 0 +LOAD 0 0 +LOAD 1 4 +INF 2 0 1 +STORE 2 2 +JMF 2 30 +AFC 0 2 +STORE 1 0 +LOAD 0 0 +LOAD 1 1 +ADD 0 0 1 +STORE 4 0 +LOAD 0 4 +STORE 0 0 +JMP 14 +NOP \ No newline at end of file diff --git a/compilateur/asm3 b/compilateur/asm3 new file mode 100644 index 0000000..8bc10dd --- /dev/null +++ b/compilateur/asm3 @@ -0,0 +1 @@ +((x"06000500"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000800"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"07000200"),(x"0C020000"),(x"08030200"),(x"10031E00"),(x"06001400"),(x"08040000"),(x"07000000"),(x"07010400"),(x"09020001"),(x"08020200"),(x"10021E00"),(x"06000200"),(x"08010000"),(x"07000000"),(x"07010100"),(x"01000001"),(x"08040000"),(x"07000400"),(x"08000000"),(x"0F0E0000"),(x"FF000000"),others => (x"ff000000")) \ No newline at end of file diff --git a/compilateur/asmTable.c b/compilateur/asmTable.c new file mode 100644 index 0000000..875c979 --- /dev/null +++ b/compilateur/asmTable.c @@ -0,0 +1,109 @@ + +#include +#include "asmTable.h" +#include "stdlib.h" +#include + +static int labelCounter = 0; + +/*At the start of the execution : the whole array is empty*/ +static ASMLine* asmTable; +static int lineCounter = 0; +static int maxIndex = START_TABLE_SIZE; + + +#include "asmTable.h" +#include "table.h" + +/* /!\ To be called at the beginning + * Initializes the array of Symbols*/ +void initASMTable(){ + asmTable = malloc(sizeof(ASMLine) * START_TABLE_SIZE); +} + +/*Checks for the length of the array and reallocates if necessary*/ +void checkASMArraySanity(){ + if (lineCounter == maxIndex){ + reallocateASMArray(maxIndex * 2); + } +} + +/*reallocates the array with the specified size*/ +void reallocateASMArray(int size){ + ASMLine *temp = (ASMLine*) realloc(asmTable, (sizeof(ASMLine) * size)); + if (temp != NULL){ + asmTable = temp; + } + else { + error("Cannot allocate more memory.\n"); + } +} + +/*inserts an asm code line at the current index*/ +void addLine(char* s) { + strcpy(asmTable[lineCounter].name,s); + asmTable[lineCounter].jumpLine = -1; + asmTable[lineCounter].conditionAddr = -1; + lineCounter++; + checkASMArraySanity(); + displayASMTable(); +} + +/*inserts the address in case of jumps*/ +void setJumpLine(int index, int addr) { + asmTable[index].jumpLine = addr; + displayASMTable(); +} + + +/*inserts the condition's address in case of jumps*/ +void setConditionAddr(int index, int addr) { + asmTable[index].conditionAddr = addr; + displayASMTable(); +} + +/*returns the current line (i.e. next one to insert)*/ +int getCurrentLineNumber() { + return lineCounter; +} + +/*displays the entire table at this moment*/ +void displayASMTable(){ + printf("\n"); + doubleLine(); + for (int i = 0; i < lineCounter; ++i) { + ASMLine a = asmTable[i]; + if(a.jumpLine == -1) { + printf("%d | %s\n", i, a.name); + } else { + if(a.conditionAddr == -1) { + printf("%d | %s %d\n", i, a.name,a.jumpLine); + } else { + printf("%d | %s %d %d\n", i, a.name,a.conditionAddr,a.jumpLine); + } + } + if (i != lineCounter -1) { + line(); + } + } + doubleLine(); +} + +/*exports the entire table to asm*/ +void exportASMTable(){ + FILE* fp; + fp = fopen("asm", "a"); + for (int i = 0; i < lineCounter; ++i) { + ASMLine a = asmTable[i]; + if(a.jumpLine == -1) { + fprintf(fp,"%s\n", a.name); + } else { + if(a.conditionAddr == -1) { + fprintf(fp,"%s %d\n", a.name,a.jumpLine); + } else { + fprintf(fp,"%s %d %d\n", a.name,a.conditionAddr,a.jumpLine); + } + } + } + fclose(fp); +} \ No newline at end of file diff --git a/compilateur/asmTable.h b/compilateur/asmTable.h new file mode 100644 index 0000000..489db7c --- /dev/null +++ b/compilateur/asmTable.h @@ -0,0 +1,48 @@ +// +// Created by chepycou on 4/18/23. +// + +#ifndef PROJET_SYSTEMES_INFORMATIQUES_ASMTABLE_H +#define PROJET_SYSTEMES_INFORMATIQUES_ASMTABLE_H + +#define START_TABLE_SIZE 128 +#define LINE_MAX_LENGTH 50 + +typedef struct { + char name[LINE_MAX_LENGTH]; + int conditionAddr; + int jumpLine; +} ASMLine; + +/*============================ + Array and Reallocation + ============================*/ + +/*reallocates the array with the specified size*/ +void reallocateASMArray(int size); + +/*Checks for the length of the array and reallocates if necessary*/ +void checkASMArraySanity(); + +/*inserts an asm code line at the current index*/ +void addLine(char* s); + +/* /!\ To be called at the beginning + * Initializes the array of Symbols*/ +void initASMTable(); + +/*inserts the address in case of jumps*/ +void setJumpLine(int index, int addr); + +/*inserts the condition's address in case of jumps*/ +void setConditionAddr(int index, int addr); + +/*returns the current line (i.e. next one to insert)*/ +int getCurrentLineNumber(); + +/*displays the entire table at this moment*/ +void displayASMTable(); + +/*exports the entire table to asm*/ +void exportASMTable(); +#endif //PROJET_SYSTEMES_INFORMATIQUES_ASMTABLE_H diff --git a/compilateur/asmTable.o b/compilateur/asmTable.o new file mode 100644 index 0000000..4f7a112 Binary files /dev/null and b/compilateur/asmTable.o differ diff --git a/compilateur/blocs.c b/compilateur/blocs.c new file mode 100644 index 0000000..c9a601d --- /dev/null +++ b/compilateur/blocs.c @@ -0,0 +1,59 @@ +// +// Created by chepycou on 4/18/23. +// + +#include "blocs.h" +#include "operations.h" +#include +#include + +/*TODO on écrit tout dans un fichier asm extérieur puis on : + * - fait un parcours pour stocker dans une liste chaînée par exemple les valeur de ligne des labels + * - faire un parcours pour retirer les labels au début des lignes + * - faire un parcours pour remplacer les labels par leur valeur + * */ +/* +int labelCount = 0; + +int getNextLabel(){ + return(labelCount++); +} + + +void printLabel(int labelWhile){ + char label[LABEL_MAX_LENGTH]; + sprintf(label,"%d_LABEL\n",labelWhile); + printf("%s",label); + FILE* fp; + fp = fopen("asm", "a"); + fputs(label, fp); + fclose(fp); +} + +int printNewLabel(){ + int l = getNextLabel(); + printLabel(l); + return l; +} + +void printJumpToLabel(int labelWhile) { + char instr[ASM_TEXT_LEN]; + sprintf(instr,"JMP %d_LABEL\n",labelWhile); + printf("%s",instr); + FILE* fp; + fp = fopen("asm", "a"); + fputs(instr, fp); + fclose(fp); +} + +void printJumpFToLabel(int labelWhile) { + char label[LABEL_MAX_LENGTH]; + sprintf(label,"%d_LABEL\n",labelWhile); + printf("JMF %s",label); + FILE* fp; + fp = fopen("asm", "a"); + fputs(label, fp); + fclose(fp); +}*/ + + diff --git a/compilateur/blocs.h b/compilateur/blocs.h new file mode 100644 index 0000000..1cddf09 --- /dev/null +++ b/compilateur/blocs.h @@ -0,0 +1,26 @@ +// +// Created by chepycou on 4/18/23. +// + +#ifndef PROJET_SYSTEMES_INFORMATIQUES_BLOCS_H +#define PROJET_SYSTEMES_INFORMATIQUES_BLOCS_H + +#define LABEL_MAX_LENGTH 20 + +/*====================== + Label Management + ======================*/ + +/*returns the next label*/ +int getNextLabel(); + +// prints a new label and returns the index of it +int printNewLabel(); + +// prints a label and returns the index of it +void printLabel(int labelWhile); + +// prints a jump to the label and returns the index of it +void printJumpToLabel(int labelWhile); + +#endif //PROJET_SYSTEMES_INFORMATIQUES_BLOCS_H diff --git a/compilateur/blocs.o b/compilateur/blocs.o new file mode 100644 index 0000000..b89fb2b Binary files /dev/null and b/compilateur/blocs.o differ diff --git a/compilateur/lex.l b/compilateur/lex.l new file mode 100644 index 0000000..f4da442 --- /dev/null +++ b/compilateur/lex.l @@ -0,0 +1,71 @@ +%{ +#include "table.h" +#include "yacc.tab.h" +%} + +/*options for compiling*/ +%option noyywrap +%option noinput +%option nounput + + + /*definition of the different types of comments*/ +M_COMMENT (\/\/).* +S_COMMENT \/\*(.|\n)*?\*\/ + + + /*definition of the Ids and types of ints*/ +ID [a-zA-Z][a-zA-Z0-9]* +INT_DEC [0-9]+ +INT_HEX 0x[0-9a-fA-F]+ + + +%% + + +"if" return(tIF); +"else" return(tELSE); +"while" return(tWHILE); +"print" return(tPRINT); +"return" return(tRETURN); +"float" return(tFLOAT); +"int" return(tINT); +"void" return(tVOID); +"+" return(tADD); +"-" return(tSUB); +"*" return(tMUL); +"/" return(tDIV); +"<" return(tLT); +">" return(tGT); +"!=" return(tNE); +"==" return(tEQ); +">=" return(tGE); +"<=" return(tLE); +"=" return(tASSIGN); +"&&" return(tAND); +"||" return(tOR); +"!" return(tNOT); +"{" return(tLBRACE); +"}" return(tRBRACE); +"(" return(tLPAR); +")" return(tRPAR); +";" return(tSEMI); +"," return(tCOMMA); + +{ID} {strncpy(yylval.str, yytext, NAME_MAX_LENGTH); return(tID);} +{INT_DEC} {yylval.nbInt = atoi(yytext); return(tNB);} +{INT_HEX} {yylval.nbInt = atoi(yytext); return(tNB);} + + + /*comments are ignored, same for spaces and lines*/ +{M_COMMENT} ; +{S_COMMENT} ; +[ ]+ ; +\n ; + + /*anything else is considered an error*/ +. yyerror(yytext); + +%% + + // SI >> SC diff --git a/compilateur/lex.yy.c b/compilateur/lex.yy.c new file mode 100644 index 0000000..3d7af89 --- /dev/null +++ b/compilateur/lex.yy.c @@ -0,0 +1,1941 @@ + +#line 2 "lex.yy.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap() (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 37 +#define YY_END_OF_BUFFER 38 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[77] = + { 0, + 0, 0, 38, 36, 35, 34, 22, 36, 25, 26, + 11, 9, 28, 10, 12, 30, 30, 27, 13, 19, + 14, 29, 29, 29, 29, 29, 29, 29, 29, 23, + 36, 24, 34, 15, 20, 0, 32, 30, 0, 18, + 16, 17, 29, 29, 29, 1, 29, 29, 29, 29, + 29, 21, 0, 0, 32, 31, 29, 29, 7, 29, + 29, 29, 29, 33, 2, 29, 29, 29, 8, 29, + 6, 4, 29, 3, 5, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 4, 1, 1, 1, 1, 5, 1, 6, + 7, 8, 9, 10, 11, 1, 12, 13, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 1, 15, 16, + 17, 18, 1, 1, 19, 19, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 1, 1, 1, 1, 1, 1, 21, 19, 19, 22, + + 23, 24, 20, 25, 26, 20, 20, 27, 20, 28, + 29, 30, 20, 31, 32, 33, 34, 35, 36, 37, + 20, 20, 38, 39, 40, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[41] = + { 0, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 3, 1, 1, 1, 1, 3, 4, + 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 1, 1, 1 + } ; + +static const flex_int16_t yy_base[81] = + { 0, + 0, 0, 99, 100, 100, 95, 80, 91, 100, 100, + 100, 100, 100, 100, 33, 29, 33, 100, 78, 77, + 76, 0, 65, 64, 20, 59, 66, 59, 62, 100, + 47, 100, 82, 100, 100, 76, 0, 36, 0, 100, + 100, 100, 0, 51, 53, 0, 48, 54, 46, 52, + 51, 100, 66, 43, 0, 0, 42, 43, 0, 35, + 28, 39, 33, 51, 0, 25, 24, 25, 0, 31, + 0, 0, 25, 0, 0, 100, 64, 68, 72, 49 + } ; + +static const flex_int16_t yy_def[81] = + { 0, + 76, 1, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 77, 77, 77, 77, 77, 77, 77, 77, 76, + 76, 76, 76, 76, 76, 78, 79, 76, 80, 76, + 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 76, 78, 78, 79, 80, 77, 77, 77, 77, + 77, 77, 77, 78, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 0, 76, 76, 76, 76 + } ; + +static const flex_int16_t yy_nxt[141] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 22, + 22, 22, 23, 24, 22, 25, 22, 22, 22, 26, + 27, 22, 22, 22, 28, 29, 22, 30, 31, 32, + 36, 38, 38, 46, 37, 38, 38, 47, 38, 38, + 54, 56, 75, 74, 64, 73, 72, 71, 54, 70, + 69, 68, 67, 66, 65, 39, 43, 43, 53, 53, + 53, 53, 55, 54, 55, 55, 63, 62, 61, 60, + 59, 58, 57, 54, 33, 52, 51, 50, 49, 48, + 45, 44, 42, 41, 40, 35, 34, 33, 76, 3, + + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76 + } ; + +static const flex_int16_t yy_chk[141] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 15, 16, 16, 25, 15, 17, 17, 25, 38, 38, + 54, 80, 73, 70, 54, 68, 67, 66, 64, 63, + 62, 61, 60, 58, 57, 16, 77, 77, 78, 78, + 78, 78, 79, 53, 79, 79, 51, 50, 49, 48, + 47, 45, 44, 36, 33, 31, 29, 28, 27, 26, + 24, 23, 21, 20, 19, 8, 7, 6, 3, 76, + + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "lex.l" +#line 2 "lex.l" +#include "table.h" +#include "yacc.tab.h" +#line 498 "lex.yy.c" +/*options for compiling*/ +#define YY_NO_INPUT 1 +#line 13 "lex.l" + /*definition of the different types of comments*/ + /*definition of the Ids and types of ints*/ +#line 504 "lex.yy.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 24 "lex.l" + + + +#line 723 "lex.yy.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 77 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 100 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 27 "lex.l" +return(tIF); + YY_BREAK +case 2: +YY_RULE_SETUP +#line 28 "lex.l" +return(tELSE); + YY_BREAK +case 3: +YY_RULE_SETUP +#line 29 "lex.l" +return(tWHILE); + YY_BREAK +case 4: +YY_RULE_SETUP +#line 30 "lex.l" +return(tPRINT); + YY_BREAK +case 5: +YY_RULE_SETUP +#line 31 "lex.l" +return(tRETURN); + YY_BREAK +case 6: +YY_RULE_SETUP +#line 32 "lex.l" +return(tFLOAT); + YY_BREAK +case 7: +YY_RULE_SETUP +#line 33 "lex.l" +return(tINT); + YY_BREAK +case 8: +YY_RULE_SETUP +#line 34 "lex.l" +return(tVOID); + YY_BREAK +case 9: +YY_RULE_SETUP +#line 35 "lex.l" +return(tADD); + YY_BREAK +case 10: +YY_RULE_SETUP +#line 36 "lex.l" +return(tSUB); + YY_BREAK +case 11: +YY_RULE_SETUP +#line 37 "lex.l" +return(tMUL); + YY_BREAK +case 12: +YY_RULE_SETUP +#line 38 "lex.l" +return(tDIV); + YY_BREAK +case 13: +YY_RULE_SETUP +#line 39 "lex.l" +return(tLT); + YY_BREAK +case 14: +YY_RULE_SETUP +#line 40 "lex.l" +return(tGT); + YY_BREAK +case 15: +YY_RULE_SETUP +#line 41 "lex.l" +return(tNE); + YY_BREAK +case 16: +YY_RULE_SETUP +#line 42 "lex.l" +return(tEQ); + YY_BREAK +case 17: +YY_RULE_SETUP +#line 43 "lex.l" +return(tGE); + YY_BREAK +case 18: +YY_RULE_SETUP +#line 44 "lex.l" +return(tLE); + YY_BREAK +case 19: +YY_RULE_SETUP +#line 45 "lex.l" +return(tASSIGN); + YY_BREAK +case 20: +YY_RULE_SETUP +#line 46 "lex.l" +return(tAND); + YY_BREAK +case 21: +YY_RULE_SETUP +#line 47 "lex.l" +return(tOR); + YY_BREAK +case 22: +YY_RULE_SETUP +#line 48 "lex.l" +return(tNOT); + YY_BREAK +case 23: +YY_RULE_SETUP +#line 49 "lex.l" +return(tLBRACE); + YY_BREAK +case 24: +YY_RULE_SETUP +#line 50 "lex.l" +return(tRBRACE); + YY_BREAK +case 25: +YY_RULE_SETUP +#line 51 "lex.l" +return(tLPAR); + YY_BREAK +case 26: +YY_RULE_SETUP +#line 52 "lex.l" +return(tRPAR); + YY_BREAK +case 27: +YY_RULE_SETUP +#line 53 "lex.l" +return(tSEMI); + YY_BREAK +case 28: +YY_RULE_SETUP +#line 54 "lex.l" +return(tCOMMA); + YY_BREAK +case 29: +YY_RULE_SETUP +#line 56 "lex.l" +{strncpy(yylval.str, yytext, NAME_MAX_LENGTH); return(tID);} + YY_BREAK +case 30: +YY_RULE_SETUP +#line 57 "lex.l" +{yylval.nbInt = atoi(yytext); return(tNB);} + YY_BREAK +case 31: +YY_RULE_SETUP +#line 58 "lex.l" +{yylval.nbInt = atoi(yytext); return(tNB);} + YY_BREAK +/*comments are ignored, same for spaces and lines*/ +case 32: +YY_RULE_SETUP +#line 62 "lex.l" +; + YY_BREAK +case 33: +/* rule 33 can match eol */ +YY_RULE_SETUP +#line 63 "lex.l" +; + YY_BREAK +case 34: +YY_RULE_SETUP +#line 64 "lex.l" +; + YY_BREAK +case 35: +/* rule 35 can match eol */ +YY_RULE_SETUP +#line 65 "lex.l" +; + YY_BREAK +/*anything else is considered an error*/ +case 36: +YY_RULE_SETUP +#line 68 "lex.l" +yyerror(yytext); + YY_BREAK +case 37: +YY_RULE_SETUP +#line 70 "lex.l" +ECHO; + YY_BREAK +#line 969 "lex.yy.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 77 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 77 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 76); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 70 "lex.l" + + + // SI >> SC + diff --git a/compilateur/lex.yy.o b/compilateur/lex.yy.o new file mode 100644 index 0000000..e39f062 Binary files /dev/null and b/compilateur/lex.yy.o differ diff --git a/compilateur/operations.c b/compilateur/operations.c new file mode 100644 index 0000000..0a2de43 --- /dev/null +++ b/compilateur/operations.c @@ -0,0 +1,168 @@ +// +// Created by chepycou on 4/14/23. +// + +#include +#include "table.h" +#include "operations.h" +#include "asmTable.h" + +/*prints to the stdout and the out asm file*/ +void printOp(char* s){ + //printf("%s",s); + addLine(s); + + /*FILE* fp; + fp = fopen("asm", "a"); + fputs(s, fp); + fclose(fp);*/ +} + +/*clears the out asm file*/ +void clearOp(){ + FILE* fp; + fp = fopen("asm", "w"); + fclose(fp); +} + +/*prints the ASM instruction for the addition computation + * and returns the address of the temporary variable*/ +int operation_add(int addr1, int addr2){ + int addr = addTempINTAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "ADD %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the subtraction computation + * and returns the address of the temporary variable*/ +int operation_sub(int addr1, int addr2){ + int addr = addTempINTAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "SUB %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the multiplication computation + * and returns the address of the temporary variable*/ +int operation_mul(int addr1, int addr2){ + int addr = addTempINTAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "MUL %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the integer division computation + * and returns the address of the temporary variable*/ +int operation_divInt(int addr1, int addr2){ + int addr = addTempINTAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "DIV_INT %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the remainder computation + * and returns the address of the temporary variable*/ +int operation_divRem(int addr1, int addr2){ + int addr = addTempINTAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "DIV_REM %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the affection of a variable + * EX : + * a = 2; + */ +void operation_afc_nb(int addr, int value){ + char s[ASM_TEXT_LEN]; + sprintf(s, "AFC %d %d", addr, value); + printOp(s); +} + +/*prints the ASM instruction for the affection of a temporary variable + * EX : + * "1_TEMP = 2" + * and returns the address of the temp variable*/ +int operation_afc_nb_tmp(int value){ + int addr = addTempINTAndGetAddress(); + operation_afc_nb(addr, value); + return addr; +} + + +/*prints the ASM instruction for the affection of a temporary variable + * EX : + * a = b; + */ +void operation_copy(int addr1, int addr2){ + char s[ASM_TEXT_LEN]; + sprintf(s, "COP %d %d", addr1, addr2); + printOp(s); +} + +/*prints the ASM instruction for the inferior condition + * and returns the address of the temporary variable*/ +int cond_inf(int addr1, int addr2){ + int addr = addTempCONDAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "INF %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the superior condition + * and returns the address of the temporary variable*/ +int cond_sup(int addr1, int addr2){ + int addr = addTempCONDAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "SUP %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the equality condition + * and returns the address of the temporary variable*/ +int cond_eq(int addr1, int addr2) { + int addr = addTempCONDAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "EQ %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the negation condition + * and returns the address of the temporary variable*/ +int cond_not(int addr1){ + int addr = addTempCONDAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "NOT %d %d", addr, addr1); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the and condition + * and returns the address of the temporary variable*/ +int cond_and(int addr1, int addr2){ + int addr = addTempCONDAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "AND %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + +/*prints the ASM instruction for the or condition + * and returns the address of the temporary variable*/ +int cond_or(int addr1, int addr2){ + int addr = addTempCONDAndGetAddress(); + char s[ASM_TEXT_LEN]; + sprintf(s, "OR %d %d %d", addr, addr1, addr2); + printOp(s); + return addr; +} + diff --git a/compilateur/operations.h b/compilateur/operations.h new file mode 100644 index 0000000..c525bc2 --- /dev/null +++ b/compilateur/operations.h @@ -0,0 +1,78 @@ +// +// Created by chepycou on 4/14/23. +// + +#ifndef PROJET_SYSTEMES_INFORMATIQUES_OPERATIONS_H +#define PROJET_SYSTEMES_INFORMATIQUES_OPERATIONS_H + +#define ASM_TEXT_LEN 40 + +/*clears the out asm file*/ +void clearOp(); + +/*prints to the stdout and the out asm file*/ +void printOp(char* s); + +/*prints the ASM instruction for the addition computation + * and returns the address of the temporary variable*/ +int operation_add(int addr1, int addr2); + +/*prints the ASM instruction for the subtraction computation + * and returns the address of the temporary variable*/ +int operation_sub(int addr1, int addr2); + +/*prints the ASM instruction for the multiplication computation + * and returns the address of the temporary variable*/ +int operation_mul(int addr1, int addr2); + +/*prints the ASM instruction for the integer division computation + * and returns the address of the temporary variable*/ +int operation_divInt(int addr1, int addr2); + +/*prints the ASM instruction for the remainder computation + * and returns the address of the temporary variable*/ +int operation_divRem(int addr1, int addr2); + +/*prints the ASM instruction for the affection of a variable + * EX : + * a = 2; + */ +void operation_afc_nb(int addr, int value); + +/*prints the ASM instruction for the affection of a temporary variable + * EX : + * "1_TEMP = 2" + * and returns the address of the temp variable*/ +int operation_afc_nb_tmp(int value); + +/*prints the ASM instruction for the affection of a temporary variable + * EX : + * a = b; + */ +void operation_copy(int addr1, int addr2); + +/*prints the ASM instruction for the inferior condition + * and returns the address of the temporary variable*/ +int cond_inf(int addr1, int addr2); + +/*prints the ASM instruction for the superior condition + * and returns the address of the temporary variable*/ +int cond_sup(int addr1, int addr2); + +/*prints the ASM instruction for the equality condition + * and returns the address of the temporary variable*/ +int cond_eq(int addr1, int addr2); + +/*prints the ASM instruction for the negation condition + * and returns the address of the temporary variable*/ +int cond_not(int addr1); + +/*prints the ASM instruction for the and condition + * and returns the address of the temporary variable*/ +int cond_and(int addr1, int addr2); + +/*prints the ASM instruction for the or condition + * and returns the address of the temporary variable*/ +int cond_or(int addr1, int addr2); + +#endif //PROJET_SYSTEMES_INFORMATIQUES_OPERATIONS_H diff --git a/compilateur/operations.o b/compilateur/operations.o new file mode 100644 index 0000000..48cf6e8 Binary files /dev/null and b/compilateur/operations.o differ diff --git a/compilateur/out b/compilateur/out new file mode 100755 index 0000000..52552e0 Binary files /dev/null and b/compilateur/out differ diff --git a/compilateur/table.c b/compilateur/table.c new file mode 100644 index 0000000..1358d85 --- /dev/null +++ b/compilateur/table.c @@ -0,0 +1,308 @@ +#include +#include +#include "table.h" + +#define VERBOSITY 0 // 1 -> displays the table, 0 no display + +int memorySizes[2] = {1,1}; +int tempCounter = 0; +int condCounter = 0; // to store whether there is a conditional variable + +/*At the start of the execution : the whole array is empty*/ +static Symbol* symbolTable; + +/*indexes in the array*/ +static int currentIndex = 0; // the next to index to be used +static int maxIndex = START_TABLE_SIZE; + +// stack pointers +static int esp = 0; +static int ebp = 0; + +static int currentDepth = 0; + +/* /!\ To be called at the beginning + * Initializes the array of Symbols*/ +void initSymbolTable(){ + symbolTable = malloc(sizeof(Symbol) * START_TABLE_SIZE); +} + +/*resets the symbol table*/ +void resetSymboltable(){ + currentIndex = 0; + maxIndex = START_TABLE_SIZE; + +// stack pointers + esp = 0; + ebp = 0; + + currentDepth = 0; +} + + +/* Error display */ +void error(char* mess){ + printf("ERROR : %s\n", mess); + exit(-1); +} + +/* Returns the offset from EBP to the symbol in the stack */ +int getOffset(char* name){ + return (ebp + getStruct(name).offset); +} + +/* Returns the structure with this name */ +Symbol getStruct(char* name){ + for(int i=0; i < currentIndex; i++){ + if (strcmp(symbolTable[i].name, name) == 0){ + return symbolTable[i]; + } + } + if (VERBOSITY) { + printf("\n\n%s not found \n\n", name); + displayTable(); + } + error("No structure found"); + return (createNewStructure("error", 0)); +} + +/* Returns the index with this name*/ +int getIndex(char* name){ + for(int i=0; i < currentIndex; i++){ + if (strcmp(symbolTable[i].name, name) == 0){ + return i; + } + } + printf("%s",name); + error("No index found"); + return (0); +} + +/* removes all symbols associated with the current Depth*/ +void clearOutOfScopeVariable(){ + int i = 0; + int memoryFreed = 0; + + // we get to the first symbol that we need to remove + while(i < currentIndex) { + if (symbolTable[i].depth == currentDepth) { + break; + } + i++; + } + + int futureCurrentIndex = i; + + while(i < currentIndex) { + memoryFreed += memorySizes[symbolTable[i].varType]; + i++; + } + + // now we remove all the symbols + currentIndex = futureCurrentIndex; + checkArraySanity(); + + // and we free their memory (i.e. decrease esp) + esp -= memoryFreed; + + if (VERBOSITY) { + printf("\n\nclearOutOfScopeVariable::After"); + displayTable(); + } +} + + +/* sets the init state of the symbol to true */ +void setInit(char *name){ + symbolTable[getIndex(name)].init = true; + + if (VERBOSITY) { + printf("\n\nsetInit %s", name); + displayTable(); + } +} + +/*creates a new structure and updates variables*/ +Symbol createNewStructure(char* name, enumVarType type){ + Symbol s; + strcpy(s.name,name); + s.init = false; + s.varType = type; + s.offset = esp; // the offset is the current esp + s.depth = currentDepth; + return s; +} + + +/* Adds an element */ +void addElement(char* name, enumVarType type){ + + Symbol element = createNewStructure(name, type); + + //checks for overflow + checkArraySanity(); + + symbolTable[currentIndex] = element; + currentIndex ++; + + esp += memorySizes[type]; + + if (VERBOSITY) { + printf("\n\nAddElement %s", name); + displayTable(); + } +} + +/* Adds an element and returns the offset of it */ +int addElementAndGetAddress(char* name, enumVarType type){ + addElement(name,type); + return getOffset(name); +} + +/* Adds a temporary Int element and returns the offset of it */ +int addTempINTAndGetAddress(){ + char name[NAME_MAX_LENGTH]; + if (tempCounter == 0){ + // we create the first temporary variable and use it + addElement("0_TEMP_INT",INT); + strcpy(name, "0_TEMP_INT"); + } else if (tempCounter == 1) { + // we create the second temporary variable and use it + addElement("1_TEMP_INT",INT); + strcpy(name, "1_TEMP_INT"); + } else { + // we use the right temporary variable + sprintf(name, "%d_TEMP_INT", tempCounter % 2); + } + tempCounter++; + return getOffset(name); +} + +/* removes all symbols */ +void flushSymbolTable(){ + currentIndex = 0; + checkArraySanity(); + if (VERBOSITY) { + printf("\n\nflushSymbolTable::After"); + displayTable(); + } +} + + +/*Checks for the length of the array and reallocates if necessary*/ +void checkArraySanity(){ + if (currentIndex == maxIndex){ + reallocateArray(maxIndex * 2); + } else { + if (currentIndex < maxIndex / 2 && maxIndex / 2 > START_TABLE_SIZE){ + reallocateArray(maxIndex / 2); + } + } +} + +/*reallocates the array with the specified size*/ +void reallocateArray(int size){ + Symbol *temp = (Symbol *)realloc(symbolTable, (sizeof(Symbol) * size)); + + if (temp != NULL){ + symbolTable = temp; + } + else { + error("Cannot allocate more memory.\n"); + } +} + + +/*increases the depth (i.e. when entering a block)*/ +void increaseDepth(){ + currentDepth++; +} + +/*decreases the depth (i.e. when leaving a block)*/ +void decreaseDepth(){ + clearOutOfScopeVariable(); + currentDepth--; +} + +/*displays the entire table at this moment including all information + * regarding the symbols and the current depth*/ +void displayTable(){ + printf("\n"); + doubleLine(); + printf("Table of Symbols, depth = %d, length = %d, ESP = %d, EBP = %d\n", currentDepth, currentIndex, esp ,ebp); + printf("Name | init?, varType, offset, depth\n"); + doubleLine(); + for (int i = 0; i < currentIndex; ++i) { + Symbol a = symbolTable[i]; + printf("%s | %d, %d, %d, %d\n", a.name, a.init, a.varType, a.offset, a.depth); + if (i != currentIndex -1) { + line(); + } + } + doubleLine(); +} + +/*removes all temporary variables used for INTs*/ +void suppressTempINTElements(){ + if (tempCounter == 1){ + suppressElement("0_TEMP_INT"); + esp--; + } else { + if (tempCounter > 1){ + suppressElement("0_TEMP_INT"); + suppressElement("1_TEMP_INT"); + esp-= 2; + } + } + tempCounter = 0; +} + +/*removes one element*/ +void suppressElement(char* name){ + for(int i = getIndex(name); i < (currentIndex - 1); i ++){ + symbolTable[i] = symbolTable[i+1]; + } + currentIndex--; + checkArraySanity(); +} + +void line(){ + printf("---------------------------------\n"); +} +void doubleLine(){ + printf("============================================================\n"); +} + +/*removes all temporary variables used for CONDITIONS*/ +void suppressCONDElements(){ + if (condCounter == 1){ + suppressElement("0_TEMP_COND"); + esp--; + } else { + if (condCounter > 1){ + suppressElement("0_TEMP_COND"); + suppressElement("1_TEMP_COND"); + esp-= 2; + } + } + condCounter = 0; +} + +/* Adds a temporary Conditional element and returns the offset of it */ +int addTempCONDAndGetAddress(){ + char name[NAME_MAX_LENGTH]; + if (condCounter == 0){ + // we create the first temporary variable and use it + addElement("0_TEMP_COND",INT); + strcpy(name, "0_TEMP_COND"); + } else if (condCounter == 1) { + // we create the second temporary variable and use it + addElement("1_TEMP_COND",INT); + strcpy(name, "1_TEMP_COND"); + } else { + // we use the right temporary variable + sprintf(name, "%d_TEMP_COND", condCounter % 2); + } + condCounter++; + return getOffset(name); +} diff --git a/compilateur/table.h b/compilateur/table.h new file mode 100644 index 0000000..6bc27c6 --- /dev/null +++ b/compilateur/table.h @@ -0,0 +1,125 @@ +#ifndef TABLE_H +#define TABLE_H + +#include +#include + +/*defined constants*/ +#define START_TABLE_SIZE 128 +#define NAME_MAX_LENGTH 30 + +// a list of all type +typedef enum enumVarType {INT, FLOAT} enumVarType; + +// a list of all type's sizes +extern int memorySizes[2]; + +typedef struct { + char name[NAME_MAX_LENGTH]; + bool init; + enumVarType varType; + int offset; + int depth; +} Symbol; + +/*============================ + Array and Reallocation + ============================*/ + +/*reallocates the array with the specified size*/ +void reallocateArray(int size); + +/*Checks for the length of the array and reallocates if necessary*/ +void checkArraySanity(); + +/* /!\ To be called at the beginning + * Initializes the array of Symbols*/ +void initSymbolTable(); + +/*resets the symbol table*/ +void resetSymboltable(); + +/*inserts an asm code line at the current index*/ +void addLine(char* s); + +/*returns the current line (i.e. next one to insert)*/ +int getCurrentLineNumber(); + +/*============================ + Element Management + ============================*/ + +/* removes all symbols associated with the current Depth*/ +void clearOutOfScopeVariable(); + +/* removes all symbols */ +void flushSymbolTable(); + +/* Adds an element */ +void addElement(char* name, enumVarType type); + +/* Adds an element and returns the offset of it */ +int addElementAndGetAddress(char* name, enumVarType type); + +/* Adds a temporary Int element and returns the offset of it */ +int addTempINTAndGetAddress(); + +/* Adds a temporary Conditional element and returns the offset of it */ +int addTempCONDAndGetAddress(); + +/*creates a new structure and updates variables*/ +Symbol createNewStructure(char* name, enumVarType type); + +/*============================ + Element Edition + ============================*/ + +/* sets the init state of the symbol to true */ +void setInit(char *name); + +/*removes one element*/ +void suppressElement(char* name); + +/*removes all temporary variables used for INTs*/ +void suppressTempINTElements(); + +/*removes all temporary variables used for CONDITIONS*/ +void suppressCONDElements(); + +/*============================ + Element Access + ============================*/ + +/* Returns the index with this name*/ +int getIndex(char* name); + +/* Returns the structure with this name */ +Symbol getStruct(char* name); + +/* Returns the offset from EBP to the symbol in the stack */ +int getOffset(char* name); + + +/*========================== + Flow/Block control + =========================*/ + +/*increases the depth (i.e. when entering a block)*/ +void increaseDepth(); + +/*decreases the depth (i.e. when leaving a block)*/ +void decreaseDepth(); + +/*============================================ + Display, Todo : put in another .h file + ============================================*/ + +void error(char* mess); +void line(); +void doubleLine(); + +/*displays the entire table at this moment including all information + * regarding the symbols and the current depth*/ +void displayTable(); + +#endif diff --git a/compilateur/table.o b/compilateur/table.o new file mode 100644 index 0000000..9967ece Binary files /dev/null and b/compilateur/table.o differ diff --git a/compilateur/testFile b/compilateur/testFile new file mode 100644 index 0000000..e69de29 diff --git a/compilateur/yacc.output b/compilateur/yacc.output new file mode 100644 index 0000000..7d1cf9e --- /dev/null +++ b/compilateur/yacc.output @@ -0,0 +1,1459 @@ +Grammar + + 0 $accept: Program $end + + 1 Program: FunctionDef + 2 | FunctionDef Program + + 3 Lines: Line + 4 | Line Lines + + 5 Line: IfStatement + 6 | WhileStatement + 7 | Assignment + 8 | Declarations + 9 | FunctionCall + 10 | Return + 11 | Print + + 12 InnerBlock: tLBRACE tRBRACE + + 13 $@1: ε + + 14 InnerBlock: tLBRACE $@1 Lines tRBRACE + + 15 Condition: tLPAR ConditionalExpression tRPAR + + 16 ConditionalExpression: tID + 17 | tNB + 18 | tLPAR ConditionalExpression tRPAR + 19 | NbOrVariable tLE NbOrVariable + 20 | NbOrVariable tGE NbOrVariable + 21 | NbOrVariable tEQ NbOrVariable + 22 | NbOrVariable tNE NbOrVariable + 23 | NbOrVariable tLT NbOrVariable + 24 | NbOrVariable tGT NbOrVariable + 25 | tNOT ConditionalExpression + 26 | ConditionalExpression tOR ConditionalExpression + 27 | ConditionalExpression tAND ConditionalExpression + + 28 NbOrVariable: tID + 29 | tNB + + 30 IfStatement1: ε + + 31 $@2: ε + + 32 IfStatement: tIF Condition IfStatement1 InnerBlock tELSE $@2 InnerBlock + 33 | tIF Condition IfStatement1 InnerBlock + + 34 $@3: ε + + 35 $@4: ε + + 36 WhileStatement: tWHILE $@3 Condition $@4 InnerBlock + + 37 Assignment: tID tASSIGN Expression tSEMI + + 38 Expression: NbOrVariable + 39 | FunctionCall + 40 | tLPAR Expression tRPAR + 41 | Expression tADD Expression + 42 | Expression tSUB Expression + 43 | Expression tMUL Expression + 44 | Expression tDIV Expression + + 45 Expressions: Expression + 46 | Expression tCOMMA Expressions + + 47 FunctionCall: tID tLPAR Expressions tRPAR + + 48 FunctionDef: Type tID FunctionParams InnerBlock + 49 | tVOID tID FunctionParams InnerBlock + + 50 FunctionParams: tLPAR tRPAR + 51 | tLPAR tVOID tRPAR + 52 | tLPAR VarsWithType tRPAR + + 53 VarsWithType: VarWithType + 54 | VarWithType tCOMMA VarsWithType + + 55 VarWithType: Type tID + + 56 Type: tINT + 57 | tFLOAT + + 58 $@5: ε + + 59 Declarations: Type $@5 Declaration Declarations1 tSEMI + + 60 Declaration: tID + + 61 $@6: ε + + 62 Declaration: tID $@6 tASSIGN Expression + + 63 Declarations1: tCOMMA Declaration Declarations1 + 64 | ε + + 65 Return: tRETURN Expression tSEMI + + 66 Print: tPRINT tLPAR Expression tRPAR tSEMI + + +Terminals, with rules where they appear + + $end (0) 0 + error (256) + tELSE (258) 32 + tRETURN (259) 65 + tPRINT (260) 66 + tFLOAT (261) 57 + tINT (262) 56 + tVOID (263) 49 51 + tSUB (264) 42 + tADD (265) 41 + tMUL (266) 43 + tDIV (267) 44 + tASSIGN (268) 37 62 + tLT (269) 23 + tGT (270) 24 + tNE (271) 22 + tEQ (272) 21 + tGE (273) 20 + tLE (274) 19 + tAND (275) 27 + tOR (276) 26 + tNOT (277) 25 + tLBRACE (278) 12 14 + tRBRACE (279) 12 14 + tLPAR (280) 15 18 40 47 50 51 52 66 + tRPAR (281) 15 18 40 47 50 51 52 66 + tSEMI (282) 37 59 65 66 + tCOMMA (283) 46 54 63 + tID (284) 16 28 37 47 48 49 55 60 62 + tNB (285) 17 29 + tIF (286) 32 33 + tWHILE (287) 36 + + +Nonterminals, with rules where they appear + + $accept (33) + on left: 0 + Program (34) + on left: 1 2 + on right: 0 2 + Lines (35) + on left: 3 4 + on right: 4 14 + Line (36) + on left: 5 6 7 8 9 10 11 + on right: 3 4 + InnerBlock (37) + on left: 12 14 + on right: 32 33 36 48 49 + $@1 (38) + on left: 13 + on right: 14 + Condition (39) + on left: 15 + on right: 32 33 36 + ConditionalExpression (40) + on left: 16 17 18 19 20 21 22 23 24 25 26 27 + on right: 15 18 25 26 27 + NbOrVariable (41) + on left: 28 29 + on right: 19 20 21 22 23 24 38 + IfStatement1 (42) + on left: 30 + on right: 32 33 + IfStatement (43) + on left: 32 33 + on right: 5 + $@2 (44) + on left: 31 + on right: 32 + WhileStatement (45) + on left: 36 + on right: 6 + $@3 (46) + on left: 34 + on right: 36 + $@4 (47) + on left: 35 + on right: 36 + Assignment (48) + on left: 37 + on right: 7 + Expression (49) + on left: 38 39 40 41 42 43 44 + on right: 37 40 41 42 43 44 45 46 62 65 66 + Expressions (50) + on left: 45 46 + on right: 46 47 + FunctionCall (51) + on left: 47 + on right: 9 39 + FunctionDef (52) + on left: 48 49 + on right: 1 2 + FunctionParams (53) + on left: 50 51 52 + on right: 48 49 + VarsWithType (54) + on left: 53 54 + on right: 52 54 + VarWithType (55) + on left: 55 + on right: 53 54 + Type (56) + on left: 56 57 + on right: 48 55 59 + Declarations (57) + on left: 59 + on right: 8 + $@5 (58) + on left: 58 + on right: 59 + Declaration (59) + on left: 60 62 + on right: 59 63 + $@6 (60) + on left: 61 + on right: 62 + Declarations1 (61) + on left: 63 64 + on right: 59 63 + Return (62) + on left: 65 + on right: 10 + Print (63) + on left: 66 + on right: 11 + + +State 0 + + 0 $accept: • Program $end + + tFLOAT shift, and go to state 1 + tINT shift, and go to state 2 + tVOID shift, and go to state 3 + + Program go to state 4 + FunctionDef go to state 5 + Type go to state 6 + + +State 1 + + 57 Type: tFLOAT • + + $default reduce using rule 57 (Type) + + +State 2 + + 56 Type: tINT • + + $default reduce using rule 56 (Type) + + +State 3 + + 49 FunctionDef: tVOID • tID FunctionParams InnerBlock + + tID shift, and go to state 7 + + +State 4 + + 0 $accept: Program • $end + + $end shift, and go to state 8 + + +State 5 + + 1 Program: FunctionDef • + 2 | FunctionDef • Program + + tFLOAT shift, and go to state 1 + tINT shift, and go to state 2 + tVOID shift, and go to state 3 + + $default reduce using rule 1 (Program) + + Program go to state 9 + FunctionDef go to state 5 + Type go to state 6 + + +State 6 + + 48 FunctionDef: Type • tID FunctionParams InnerBlock + + tID shift, and go to state 10 + + +State 7 + + 49 FunctionDef: tVOID tID • FunctionParams InnerBlock + + tLPAR shift, and go to state 11 + + FunctionParams go to state 12 + + +State 8 + + 0 $accept: Program $end • + + $default accept + + +State 9 + + 2 Program: FunctionDef Program • + + $default reduce using rule 2 (Program) + + +State 10 + + 48 FunctionDef: Type tID • FunctionParams InnerBlock + + tLPAR shift, and go to state 11 + + FunctionParams go to state 13 + + +State 11 + + 50 FunctionParams: tLPAR • tRPAR + 51 | tLPAR • tVOID tRPAR + 52 | tLPAR • VarsWithType tRPAR + + tFLOAT shift, and go to state 1 + tINT shift, and go to state 2 + tVOID shift, and go to state 14 + tRPAR shift, and go to state 15 + + VarsWithType go to state 16 + VarWithType go to state 17 + Type go to state 18 + + +State 12 + + 49 FunctionDef: tVOID tID FunctionParams • InnerBlock + + tLBRACE shift, and go to state 19 + + InnerBlock go to state 20 + + +State 13 + + 48 FunctionDef: Type tID FunctionParams • InnerBlock + + tLBRACE shift, and go to state 19 + + InnerBlock go to state 21 + + +State 14 + + 51 FunctionParams: tLPAR tVOID • tRPAR + + tRPAR shift, and go to state 22 + + +State 15 + + 50 FunctionParams: tLPAR tRPAR • + + $default reduce using rule 50 (FunctionParams) + + +State 16 + + 52 FunctionParams: tLPAR VarsWithType • tRPAR + + tRPAR shift, and go to state 23 + + +State 17 + + 53 VarsWithType: VarWithType • + 54 | VarWithType • tCOMMA VarsWithType + + tCOMMA shift, and go to state 24 + + $default reduce using rule 53 (VarsWithType) + + +State 18 + + 55 VarWithType: Type • tID + + tID shift, and go to state 25 + + +State 19 + + 12 InnerBlock: tLBRACE • tRBRACE + 14 | tLBRACE • $@1 Lines tRBRACE + + tRBRACE shift, and go to state 26 + + $default reduce using rule 13 ($@1) + + $@1 go to state 27 + + +State 20 + + 49 FunctionDef: tVOID tID FunctionParams InnerBlock • + + $default reduce using rule 49 (FunctionDef) + + +State 21 + + 48 FunctionDef: Type tID FunctionParams InnerBlock • + + $default reduce using rule 48 (FunctionDef) + + +State 22 + + 51 FunctionParams: tLPAR tVOID tRPAR • + + $default reduce using rule 51 (FunctionParams) + + +State 23 + + 52 FunctionParams: tLPAR VarsWithType tRPAR • + + $default reduce using rule 52 (FunctionParams) + + +State 24 + + 54 VarsWithType: VarWithType tCOMMA • VarsWithType + + tFLOAT shift, and go to state 1 + tINT shift, and go to state 2 + + VarsWithType go to state 28 + VarWithType go to state 17 + Type go to state 18 + + +State 25 + + 55 VarWithType: Type tID • + + $default reduce using rule 55 (VarWithType) + + +State 26 + + 12 InnerBlock: tLBRACE tRBRACE • + + $default reduce using rule 12 (InnerBlock) + + +State 27 + + 14 InnerBlock: tLBRACE $@1 • Lines tRBRACE + + tRETURN shift, and go to state 29 + tPRINT shift, and go to state 30 + tFLOAT shift, and go to state 1 + tINT shift, and go to state 2 + tID shift, and go to state 31 + tIF shift, and go to state 32 + tWHILE shift, and go to state 33 + + Lines go to state 34 + Line go to state 35 + IfStatement go to state 36 + WhileStatement go to state 37 + Assignment go to state 38 + FunctionCall go to state 39 + Type go to state 40 + Declarations go to state 41 + Return go to state 42 + Print go to state 43 + + +State 28 + + 54 VarsWithType: VarWithType tCOMMA VarsWithType • + + $default reduce using rule 54 (VarsWithType) + + +State 29 + + 65 Return: tRETURN • Expression tSEMI + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 48 + FunctionCall go to state 49 + + +State 30 + + 66 Print: tPRINT • tLPAR Expression tRPAR tSEMI + + tLPAR shift, and go to state 50 + + +State 31 + + 37 Assignment: tID • tASSIGN Expression tSEMI + 47 FunctionCall: tID • tLPAR Expressions tRPAR + + tASSIGN shift, and go to state 51 + tLPAR shift, and go to state 52 + + +State 32 + + 32 IfStatement: tIF • Condition IfStatement1 InnerBlock tELSE $@2 InnerBlock + 33 | tIF • Condition IfStatement1 InnerBlock + + tLPAR shift, and go to state 53 + + Condition go to state 54 + + +State 33 + + 36 WhileStatement: tWHILE • $@3 Condition $@4 InnerBlock + + $default reduce using rule 34 ($@3) + + $@3 go to state 55 + + +State 34 + + 14 InnerBlock: tLBRACE $@1 Lines • tRBRACE + + tRBRACE shift, and go to state 56 + + +State 35 + + 3 Lines: Line • + 4 | Line • Lines + + tRETURN shift, and go to state 29 + tPRINT shift, and go to state 30 + tFLOAT shift, and go to state 1 + tINT shift, and go to state 2 + tID shift, and go to state 31 + tIF shift, and go to state 32 + tWHILE shift, and go to state 33 + + $default reduce using rule 3 (Lines) + + Lines go to state 57 + Line go to state 35 + IfStatement go to state 36 + WhileStatement go to state 37 + Assignment go to state 38 + FunctionCall go to state 39 + Type go to state 40 + Declarations go to state 41 + Return go to state 42 + Print go to state 43 + + +State 36 + + 5 Line: IfStatement • + + $default reduce using rule 5 (Line) + + +State 37 + + 6 Line: WhileStatement • + + $default reduce using rule 6 (Line) + + +State 38 + + 7 Line: Assignment • + + $default reduce using rule 7 (Line) + + +State 39 + + 9 Line: FunctionCall • + + $default reduce using rule 9 (Line) + + +State 40 + + 59 Declarations: Type • $@5 Declaration Declarations1 tSEMI + + $default reduce using rule 58 ($@5) + + $@5 go to state 58 + + +State 41 + + 8 Line: Declarations • + + $default reduce using rule 8 (Line) + + +State 42 + + 10 Line: Return • + + $default reduce using rule 10 (Line) + + +State 43 + + 11 Line: Print • + + $default reduce using rule 11 (Line) + + +State 44 + + 40 Expression: tLPAR • Expression tRPAR + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 59 + FunctionCall go to state 49 + + +State 45 + + 28 NbOrVariable: tID • + 47 FunctionCall: tID • tLPAR Expressions tRPAR + + tLPAR shift, and go to state 52 + + $default reduce using rule 28 (NbOrVariable) + + +State 46 + + 29 NbOrVariable: tNB • + + $default reduce using rule 29 (NbOrVariable) + + +State 47 + + 38 Expression: NbOrVariable • + + $default reduce using rule 38 (Expression) + + +State 48 + + 41 Expression: Expression • tADD Expression + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + 65 Return: tRETURN Expression • tSEMI + + tSUB shift, and go to state 60 + tADD shift, and go to state 61 + tMUL shift, and go to state 62 + tDIV shift, and go to state 63 + tSEMI shift, and go to state 64 + + +State 49 + + 39 Expression: FunctionCall • + + $default reduce using rule 39 (Expression) + + +State 50 + + 66 Print: tPRINT tLPAR • Expression tRPAR tSEMI + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 65 + FunctionCall go to state 49 + + +State 51 + + 37 Assignment: tID tASSIGN • Expression tSEMI + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 66 + FunctionCall go to state 49 + + +State 52 + + 47 FunctionCall: tID tLPAR • Expressions tRPAR + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 67 + Expressions go to state 68 + FunctionCall go to state 49 + + +State 53 + + 15 Condition: tLPAR • ConditionalExpression tRPAR + + tNOT shift, and go to state 69 + tLPAR shift, and go to state 70 + tID shift, and go to state 71 + tNB shift, and go to state 72 + + ConditionalExpression go to state 73 + NbOrVariable go to state 74 + + +State 54 + + 32 IfStatement: tIF Condition • IfStatement1 InnerBlock tELSE $@2 InnerBlock + 33 | tIF Condition • IfStatement1 InnerBlock + + $default reduce using rule 30 (IfStatement1) + + IfStatement1 go to state 75 + + +State 55 + + 36 WhileStatement: tWHILE $@3 • Condition $@4 InnerBlock + + tLPAR shift, and go to state 53 + + Condition go to state 76 + + +State 56 + + 14 InnerBlock: tLBRACE $@1 Lines tRBRACE • + + $default reduce using rule 14 (InnerBlock) + + +State 57 + + 4 Lines: Line Lines • + + $default reduce using rule 4 (Lines) + + +State 58 + + 59 Declarations: Type $@5 • Declaration Declarations1 tSEMI + + tID shift, and go to state 77 + + Declaration go to state 78 + + +State 59 + + 40 Expression: tLPAR Expression • tRPAR + 41 | Expression • tADD Expression + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + + tSUB shift, and go to state 60 + tADD shift, and go to state 61 + tMUL shift, and go to state 62 + tDIV shift, and go to state 63 + tRPAR shift, and go to state 79 + + +State 60 + + 42 Expression: Expression tSUB • Expression + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 80 + FunctionCall go to state 49 + + +State 61 + + 41 Expression: Expression tADD • Expression + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 81 + FunctionCall go to state 49 + + +State 62 + + 43 Expression: Expression tMUL • Expression + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 82 + FunctionCall go to state 49 + + +State 63 + + 44 Expression: Expression tDIV • Expression + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 83 + FunctionCall go to state 49 + + +State 64 + + 65 Return: tRETURN Expression tSEMI • + + $default reduce using rule 65 (Return) + + +State 65 + + 41 Expression: Expression • tADD Expression + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + 66 Print: tPRINT tLPAR Expression • tRPAR tSEMI + + tSUB shift, and go to state 60 + tADD shift, and go to state 61 + tMUL shift, and go to state 62 + tDIV shift, and go to state 63 + tRPAR shift, and go to state 84 + + +State 66 + + 37 Assignment: tID tASSIGN Expression • tSEMI + 41 Expression: Expression • tADD Expression + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + + tSUB shift, and go to state 60 + tADD shift, and go to state 61 + tMUL shift, and go to state 62 + tDIV shift, and go to state 63 + tSEMI shift, and go to state 85 + + +State 67 + + 41 Expression: Expression • tADD Expression + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + 45 Expressions: Expression • + 46 | Expression • tCOMMA Expressions + + tSUB shift, and go to state 60 + tADD shift, and go to state 61 + tMUL shift, and go to state 62 + tDIV shift, and go to state 63 + tCOMMA shift, and go to state 86 + + $default reduce using rule 45 (Expressions) + + +State 68 + + 47 FunctionCall: tID tLPAR Expressions • tRPAR + + tRPAR shift, and go to state 87 + + +State 69 + + 25 ConditionalExpression: tNOT • ConditionalExpression + + tNOT shift, and go to state 69 + tLPAR shift, and go to state 70 + tID shift, and go to state 71 + tNB shift, and go to state 72 + + ConditionalExpression go to state 88 + NbOrVariable go to state 74 + + +State 70 + + 18 ConditionalExpression: tLPAR • ConditionalExpression tRPAR + + tNOT shift, and go to state 69 + tLPAR shift, and go to state 70 + tID shift, and go to state 71 + tNB shift, and go to state 72 + + ConditionalExpression go to state 89 + NbOrVariable go to state 74 + + +State 71 + + 16 ConditionalExpression: tID • + 28 NbOrVariable: tID • + + tAND reduce using rule 16 (ConditionalExpression) + tOR reduce using rule 16 (ConditionalExpression) + tRPAR reduce using rule 16 (ConditionalExpression) + $default reduce using rule 28 (NbOrVariable) + + +State 72 + + 17 ConditionalExpression: tNB • + 29 NbOrVariable: tNB • + + tAND reduce using rule 17 (ConditionalExpression) + tOR reduce using rule 17 (ConditionalExpression) + tRPAR reduce using rule 17 (ConditionalExpression) + $default reduce using rule 29 (NbOrVariable) + + +State 73 + + 15 Condition: tLPAR ConditionalExpression • tRPAR + 26 ConditionalExpression: ConditionalExpression • tOR ConditionalExpression + 27 | ConditionalExpression • tAND ConditionalExpression + + tAND shift, and go to state 90 + tOR shift, and go to state 91 + tRPAR shift, and go to state 92 + + +State 74 + + 19 ConditionalExpression: NbOrVariable • tLE NbOrVariable + 20 | NbOrVariable • tGE NbOrVariable + 21 | NbOrVariable • tEQ NbOrVariable + 22 | NbOrVariable • tNE NbOrVariable + 23 | NbOrVariable • tLT NbOrVariable + 24 | NbOrVariable • tGT NbOrVariable + + tLT shift, and go to state 93 + tGT shift, and go to state 94 + tNE shift, and go to state 95 + tEQ shift, and go to state 96 + tGE shift, and go to state 97 + tLE shift, and go to state 98 + + +State 75 + + 32 IfStatement: tIF Condition IfStatement1 • InnerBlock tELSE $@2 InnerBlock + 33 | tIF Condition IfStatement1 • InnerBlock + + tLBRACE shift, and go to state 19 + + InnerBlock go to state 99 + + +State 76 + + 36 WhileStatement: tWHILE $@3 Condition • $@4 InnerBlock + + $default reduce using rule 35 ($@4) + + $@4 go to state 100 + + +State 77 + + 60 Declaration: tID • + 62 | tID • $@6 tASSIGN Expression + + tASSIGN reduce using rule 61 ($@6) + $default reduce using rule 60 (Declaration) + + $@6 go to state 101 + + +State 78 + + 59 Declarations: Type $@5 Declaration • Declarations1 tSEMI + + tCOMMA shift, and go to state 102 + + $default reduce using rule 64 (Declarations1) + + Declarations1 go to state 103 + + +State 79 + + 40 Expression: tLPAR Expression tRPAR • + + $default reduce using rule 40 (Expression) + + +State 80 + + 41 Expression: Expression • tADD Expression + 42 | Expression • tSUB Expression + 42 | Expression tSUB Expression • + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + + tMUL shift, and go to state 62 + tDIV shift, and go to state 63 + + $default reduce using rule 42 (Expression) + + +State 81 + + 41 Expression: Expression • tADD Expression + 41 | Expression tADD Expression • + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + + tMUL shift, and go to state 62 + tDIV shift, and go to state 63 + + $default reduce using rule 41 (Expression) + + +State 82 + + 41 Expression: Expression • tADD Expression + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 43 | Expression tMUL Expression • + 44 | Expression • tDIV Expression + + $default reduce using rule 43 (Expression) + + +State 83 + + 41 Expression: Expression • tADD Expression + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + 44 | Expression tDIV Expression • + + $default reduce using rule 44 (Expression) + + +State 84 + + 66 Print: tPRINT tLPAR Expression tRPAR • tSEMI + + tSEMI shift, and go to state 104 + + +State 85 + + 37 Assignment: tID tASSIGN Expression tSEMI • + + $default reduce using rule 37 (Assignment) + + +State 86 + + 46 Expressions: Expression tCOMMA • Expressions + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 67 + Expressions go to state 105 + FunctionCall go to state 49 + + +State 87 + + 47 FunctionCall: tID tLPAR Expressions tRPAR • + + $default reduce using rule 47 (FunctionCall) + + +State 88 + + 25 ConditionalExpression: tNOT ConditionalExpression • + 26 | ConditionalExpression • tOR ConditionalExpression + 27 | ConditionalExpression • tAND ConditionalExpression + + $default reduce using rule 25 (ConditionalExpression) + + +State 89 + + 18 ConditionalExpression: tLPAR ConditionalExpression • tRPAR + 26 | ConditionalExpression • tOR ConditionalExpression + 27 | ConditionalExpression • tAND ConditionalExpression + + tAND shift, and go to state 90 + tOR shift, and go to state 91 + tRPAR shift, and go to state 106 + + +State 90 + + 27 ConditionalExpression: ConditionalExpression tAND • ConditionalExpression + + tNOT shift, and go to state 69 + tLPAR shift, and go to state 70 + tID shift, and go to state 71 + tNB shift, and go to state 72 + + ConditionalExpression go to state 107 + NbOrVariable go to state 74 + + +State 91 + + 26 ConditionalExpression: ConditionalExpression tOR • ConditionalExpression + + tNOT shift, and go to state 69 + tLPAR shift, and go to state 70 + tID shift, and go to state 71 + tNB shift, and go to state 72 + + ConditionalExpression go to state 108 + NbOrVariable go to state 74 + + +State 92 + + 15 Condition: tLPAR ConditionalExpression tRPAR • + + $default reduce using rule 15 (Condition) + + +State 93 + + 23 ConditionalExpression: NbOrVariable tLT • NbOrVariable + + tID shift, and go to state 109 + tNB shift, and go to state 46 + + NbOrVariable go to state 110 + + +State 94 + + 24 ConditionalExpression: NbOrVariable tGT • NbOrVariable + + tID shift, and go to state 109 + tNB shift, and go to state 46 + + NbOrVariable go to state 111 + + +State 95 + + 22 ConditionalExpression: NbOrVariable tNE • NbOrVariable + + tID shift, and go to state 109 + tNB shift, and go to state 46 + + NbOrVariable go to state 112 + + +State 96 + + 21 ConditionalExpression: NbOrVariable tEQ • NbOrVariable + + tID shift, and go to state 109 + tNB shift, and go to state 46 + + NbOrVariable go to state 113 + + +State 97 + + 20 ConditionalExpression: NbOrVariable tGE • NbOrVariable + + tID shift, and go to state 109 + tNB shift, and go to state 46 + + NbOrVariable go to state 114 + + +State 98 + + 19 ConditionalExpression: NbOrVariable tLE • NbOrVariable + + tID shift, and go to state 109 + tNB shift, and go to state 46 + + NbOrVariable go to state 115 + + +State 99 + + 32 IfStatement: tIF Condition IfStatement1 InnerBlock • tELSE $@2 InnerBlock + 33 | tIF Condition IfStatement1 InnerBlock • + + tELSE shift, and go to state 116 + + $default reduce using rule 33 (IfStatement) + + +State 100 + + 36 WhileStatement: tWHILE $@3 Condition $@4 • InnerBlock + + tLBRACE shift, and go to state 19 + + InnerBlock go to state 117 + + +State 101 + + 62 Declaration: tID $@6 • tASSIGN Expression + + tASSIGN shift, and go to state 118 + + +State 102 + + 63 Declarations1: tCOMMA • Declaration Declarations1 + + tID shift, and go to state 77 + + Declaration go to state 119 + + +State 103 + + 59 Declarations: Type $@5 Declaration Declarations1 • tSEMI + + tSEMI shift, and go to state 120 + + +State 104 + + 66 Print: tPRINT tLPAR Expression tRPAR tSEMI • + + $default reduce using rule 66 (Print) + + +State 105 + + 46 Expressions: Expression tCOMMA Expressions • + + $default reduce using rule 46 (Expressions) + + +State 106 + + 18 ConditionalExpression: tLPAR ConditionalExpression tRPAR • + + $default reduce using rule 18 (ConditionalExpression) + + +State 107 + + 26 ConditionalExpression: ConditionalExpression • tOR ConditionalExpression + 27 | ConditionalExpression • tAND ConditionalExpression + 27 | ConditionalExpression tAND ConditionalExpression • + + $default reduce using rule 27 (ConditionalExpression) + + +State 108 + + 26 ConditionalExpression: ConditionalExpression • tOR ConditionalExpression + 26 | ConditionalExpression tOR ConditionalExpression • + 27 | ConditionalExpression • tAND ConditionalExpression + + $default reduce using rule 26 (ConditionalExpression) + + +State 109 + + 28 NbOrVariable: tID • + + $default reduce using rule 28 (NbOrVariable) + + +State 110 + + 23 ConditionalExpression: NbOrVariable tLT NbOrVariable • + + $default reduce using rule 23 (ConditionalExpression) + + +State 111 + + 24 ConditionalExpression: NbOrVariable tGT NbOrVariable • + + $default reduce using rule 24 (ConditionalExpression) + + +State 112 + + 22 ConditionalExpression: NbOrVariable tNE NbOrVariable • + + $default reduce using rule 22 (ConditionalExpression) + + +State 113 + + 21 ConditionalExpression: NbOrVariable tEQ NbOrVariable • + + $default reduce using rule 21 (ConditionalExpression) + + +State 114 + + 20 ConditionalExpression: NbOrVariable tGE NbOrVariable • + + $default reduce using rule 20 (ConditionalExpression) + + +State 115 + + 19 ConditionalExpression: NbOrVariable tLE NbOrVariable • + + $default reduce using rule 19 (ConditionalExpression) + + +State 116 + + 32 IfStatement: tIF Condition IfStatement1 InnerBlock tELSE • $@2 InnerBlock + + $default reduce using rule 31 ($@2) + + $@2 go to state 121 + + +State 117 + + 36 WhileStatement: tWHILE $@3 Condition $@4 InnerBlock • + + $default reduce using rule 36 (WhileStatement) + + +State 118 + + 62 Declaration: tID $@6 tASSIGN • Expression + + tLPAR shift, and go to state 44 + tID shift, and go to state 45 + tNB shift, and go to state 46 + + NbOrVariable go to state 47 + Expression go to state 122 + FunctionCall go to state 49 + + +State 119 + + 63 Declarations1: tCOMMA Declaration • Declarations1 + + tCOMMA shift, and go to state 102 + + $default reduce using rule 64 (Declarations1) + + Declarations1 go to state 123 + + +State 120 + + 59 Declarations: Type $@5 Declaration Declarations1 tSEMI • + + $default reduce using rule 59 (Declarations) + + +State 121 + + 32 IfStatement: tIF Condition IfStatement1 InnerBlock tELSE $@2 • InnerBlock + + tLBRACE shift, and go to state 19 + + InnerBlock go to state 124 + + +State 122 + + 41 Expression: Expression • tADD Expression + 42 | Expression • tSUB Expression + 43 | Expression • tMUL Expression + 44 | Expression • tDIV Expression + 62 Declaration: tID $@6 tASSIGN Expression • + + tSUB shift, and go to state 60 + tADD shift, and go to state 61 + tMUL shift, and go to state 62 + tDIV shift, and go to state 63 + + $default reduce using rule 62 (Declaration) + + +State 123 + + 63 Declarations1: tCOMMA Declaration Declarations1 • + + $default reduce using rule 63 (Declarations1) + + +State 124 + + 32 IfStatement: tIF Condition IfStatement1 InnerBlock tELSE $@2 InnerBlock • + + $default reduce using rule 32 (IfStatement) diff --git a/compilateur/yacc.tab.c b/compilateur/yacc.tab.c new file mode 100644 index 0000000..242546b --- /dev/null +++ b/compilateur/yacc.tab.c @@ -0,0 +1,1947 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output, and Bison version. */ +#define YYBISON 30802 + +/* Bison version string. */ +#define YYBISON_VERSION "3.8.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* First part of user prologue. */ +#line 3 "yacc.y" + +#include +#include +#include "table.h" +#include "operations.h" +#include "blocs.h" +#include "asmTable.h" + +int t; +int labelWhileStart; +int labelWhileEnd; +int whileJumpAddr; + +#line 85 "yacc.tab.c" + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +#include "yacc.tab.h" +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_tELSE = 3, /* tELSE */ + YYSYMBOL_tRETURN = 4, /* tRETURN */ + YYSYMBOL_tPRINT = 5, /* tPRINT */ + YYSYMBOL_tFLOAT = 6, /* tFLOAT */ + YYSYMBOL_tINT = 7, /* tINT */ + YYSYMBOL_tVOID = 8, /* tVOID */ + YYSYMBOL_tSUB = 9, /* tSUB */ + YYSYMBOL_tADD = 10, /* tADD */ + YYSYMBOL_tMUL = 11, /* tMUL */ + YYSYMBOL_tDIV = 12, /* tDIV */ + YYSYMBOL_tASSIGN = 13, /* tASSIGN */ + YYSYMBOL_tLT = 14, /* tLT */ + YYSYMBOL_tGT = 15, /* tGT */ + YYSYMBOL_tNE = 16, /* tNE */ + YYSYMBOL_tEQ = 17, /* tEQ */ + YYSYMBOL_tGE = 18, /* tGE */ + YYSYMBOL_tLE = 19, /* tLE */ + YYSYMBOL_tAND = 20, /* tAND */ + YYSYMBOL_tOR = 21, /* tOR */ + YYSYMBOL_tNOT = 22, /* tNOT */ + YYSYMBOL_tLBRACE = 23, /* tLBRACE */ + YYSYMBOL_tRBRACE = 24, /* tRBRACE */ + YYSYMBOL_tLPAR = 25, /* tLPAR */ + YYSYMBOL_tRPAR = 26, /* tRPAR */ + YYSYMBOL_tSEMI = 27, /* tSEMI */ + YYSYMBOL_tCOMMA = 28, /* tCOMMA */ + YYSYMBOL_tID = 29, /* tID */ + YYSYMBOL_tNB = 30, /* tNB */ + YYSYMBOL_tIF = 31, /* tIF */ + YYSYMBOL_tWHILE = 32, /* tWHILE */ + YYSYMBOL_YYACCEPT = 33, /* $accept */ + YYSYMBOL_Program = 34, /* Program */ + YYSYMBOL_Lines = 35, /* Lines */ + YYSYMBOL_Line = 36, /* Line */ + YYSYMBOL_InnerBlock = 37, /* InnerBlock */ + YYSYMBOL_38_1 = 38, /* $@1 */ + YYSYMBOL_Condition = 39, /* Condition */ + YYSYMBOL_ConditionalExpression = 40, /* ConditionalExpression */ + YYSYMBOL_NbOrVariable = 41, /* NbOrVariable */ + YYSYMBOL_IfStatement1 = 42, /* IfStatement1 */ + YYSYMBOL_IfStatement = 43, /* IfStatement */ + YYSYMBOL_44_2 = 44, /* $@2 */ + YYSYMBOL_WhileStatement = 45, /* WhileStatement */ + YYSYMBOL_46_3 = 46, /* $@3 */ + YYSYMBOL_47_4 = 47, /* $@4 */ + YYSYMBOL_Assignment = 48, /* Assignment */ + YYSYMBOL_Expression = 49, /* Expression */ + YYSYMBOL_Expressions = 50, /* Expressions */ + YYSYMBOL_FunctionCall = 51, /* FunctionCall */ + YYSYMBOL_FunctionDef = 52, /* FunctionDef */ + YYSYMBOL_FunctionParams = 53, /* FunctionParams */ + YYSYMBOL_VarsWithType = 54, /* VarsWithType */ + YYSYMBOL_VarWithType = 55, /* VarWithType */ + YYSYMBOL_Type = 56, /* Type */ + YYSYMBOL_Declarations = 57, /* Declarations */ + YYSYMBOL_58_5 = 58, /* $@5 */ + YYSYMBOL_Declaration = 59, /* Declaration */ + YYSYMBOL_60_6 = 60, /* $@6 */ + YYSYMBOL_Declarations1 = 61, /* Declarations1 */ + YYSYMBOL_Return = 62, /* Return */ + YYSYMBOL_Print = 63 /* Print */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; + + + + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int8 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YY_USE(E) ((void) (E)) +#else +# define YY_USE(E) /* empty */ +#endif + +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ +# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") +# else +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# endif +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if 1 + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* 1 */ + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 8 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 139 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 33 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 31 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 67 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 125 + +/* YYMAXUTOK -- Last valid token kind. */ +#define YYMAXUTOK 287 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_int8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32 +}; + +#if YYDEBUG +/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 62, 62, 63, 66, 67, 69, 70, 71, 72, + 73, 74, 75, 78, 79, 79, 83, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 102, + 103, 114, 118, 118, 123, 127, 129, 127, 142, 147, + 148, 149, 153, 154, 155, 156, 159, 160, 162, 164, + 165, 168, 169, 170, 172, 173, 176, 179, 180, 183, + 183, 185, 186, 186, 188, 188, 191, 193 +}; +#endif + +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if 1 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + static const char *const yy_sname[] = + { + "end of file", "error", "invalid token", "tELSE", "tRETURN", "tPRINT", + "tFLOAT", "tINT", "tVOID", "tSUB", "tADD", "tMUL", "tDIV", "tASSIGN", + "tLT", "tGT", "tNE", "tEQ", "tGE", "tLE", "tAND", "tOR", "tNOT", + "tLBRACE", "tRBRACE", "tLPAR", "tRPAR", "tSEMI", "tCOMMA", "tID", "tNB", + "tIF", "tWHILE", "$accept", "Program", "Lines", "Line", "InnerBlock", + "$@1", "Condition", "ConditionalExpression", "NbOrVariable", + "IfStatement1", "IfStatement", "$@2", "WhileStatement", "$@3", "$@4", + "Assignment", "Expression", "Expressions", "FunctionCall", "FunctionDef", + "FunctionParams", "VarsWithType", "VarWithType", "Type", "Declarations", + "$@5", "Declaration", "$@6", "Declarations1", "Return", "Print", YY_NULLPTR + }; + return yy_sname[yysymbol]; +} +#endif + +#define YYPACT_NINF (-52) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-63) + +#define yytable_value_is_error(Yyn) \ + 0 + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int8 yypact[] = +{ + 114, -52, -52, -12, 25, 114, -8, 13, -52, -52, + 13, 1, 18, 18, 34, -52, 35, 39, 44, 48, + -52, -52, -52, -52, 4, -52, -52, -1, -52, 94, + 55, 11, 63, -52, 67, -1, -52, -52, -52, -52, + -52, -52, -52, -52, 94, 104, -52, -52, 47, -52, + 94, 94, 94, 64, -52, 63, -52, -52, 50, 66, + 94, 94, 94, 94, -52, 73, 54, 43, 42, 64, + 64, 75, 77, 84, 99, 18, -52, 87, 74, -52, + 3, 3, -52, -52, 82, -52, 94, -52, -52, 86, + 64, 64, -52, 21, 21, 21, 21, 21, 21, 108, + 18, 117, 50, 105, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, 94, 74, + -52, 18, 116, -52, -52 +}; + +/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_int8 yydefact[] = +{ + 0, 58, 57, 0, 0, 2, 0, 0, 1, 3, + 0, 0, 0, 0, 0, 51, 0, 54, 0, 14, + 50, 49, 52, 53, 0, 56, 13, 0, 55, 0, + 0, 0, 0, 35, 0, 4, 6, 7, 8, 10, + 59, 9, 11, 12, 0, 29, 30, 39, 0, 40, + 0, 0, 0, 0, 31, 0, 15, 5, 0, 0, + 0, 0, 0, 0, 66, 0, 0, 46, 0, 0, + 0, 29, 30, 0, 0, 0, 36, 61, 65, 41, + 43, 42, 44, 45, 0, 38, 0, 48, 26, 0, + 0, 0, 16, 0, 0, 0, 0, 0, 0, 34, + 0, 0, 0, 0, 67, 47, 19, 28, 27, 29, + 24, 25, 23, 22, 21, 20, 32, 37, 0, 65, + 60, 0, 63, 64, 33 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -52, 126, 98, -52, -13, -52, 79, -21, -51, -52, + -52, -52, -52, -52, -52, -52, -28, 49, -15, -52, + 127, 112, -52, 2, -52, -52, 36, -52, 20, -52, + -52 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + 0, 4, 34, 35, 20, 27, 54, 73, 47, 75, + 36, 121, 37, 55, 100, 38, 67, 68, 49, 5, + 12, 16, 17, 6, 41, 58, 78, 101, 103, 42, + 43 +}; + +/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int8 yytable[] = +{ + 21, 48, 74, 29, 30, 1, 2, 1, 2, 14, + 1, 2, 39, 18, 62, 63, 59, 7, 74, 74, + 39, 10, 65, 66, 51, 8, 18, 15, 31, 40, + 32, 33, 80, 81, 82, 83, 52, 40, 11, 74, + 74, 19, 110, 111, 112, 113, 114, 115, 88, 89, + 109, 46, 60, 61, 62, 63, 60, 61, 62, 63, + 22, 23, 99, 60, 61, 62, 63, 24, 87, 107, + 108, 86, 26, 25, 64, 60, 61, 62, 63, 77, + 50, 85, 60, 61, 62, 63, 69, 117, 53, 70, + 122, 56, 79, 71, 72, -17, -17, -18, -18, 84, + -62, -17, 102, -18, 90, 91, 90, 91, 124, 104, + 92, 116, 106, 93, 94, 95, 96, 97, 98, 44, + 1, 2, 3, 45, 46, 60, 61, 62, 63, 52, + 118, 9, 120, 57, 76, 105, 28, 13, 119, 123 +}; + +static const yytype_int8 yycheck[] = +{ + 13, 29, 53, 4, 5, 6, 7, 6, 7, 8, + 6, 7, 27, 11, 11, 12, 44, 29, 69, 70, + 35, 29, 50, 51, 13, 0, 24, 26, 29, 27, + 31, 32, 60, 61, 62, 63, 25, 35, 25, 90, + 91, 23, 93, 94, 95, 96, 97, 98, 69, 70, + 29, 30, 9, 10, 11, 12, 9, 10, 11, 12, + 26, 26, 75, 9, 10, 11, 12, 28, 26, 90, + 91, 28, 24, 29, 27, 9, 10, 11, 12, 29, + 25, 27, 9, 10, 11, 12, 22, 100, 25, 25, + 118, 24, 26, 29, 30, 20, 21, 20, 21, 26, + 13, 26, 28, 26, 20, 21, 20, 21, 121, 27, + 26, 3, 26, 14, 15, 16, 17, 18, 19, 25, + 6, 7, 8, 29, 30, 9, 10, 11, 12, 25, + 13, 5, 27, 35, 55, 86, 24, 10, 102, 119 +}; + +/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of + state STATE-NUM. */ +static const yytype_int8 yystos[] = +{ + 0, 6, 7, 8, 34, 52, 56, 29, 0, 34, + 29, 25, 53, 53, 8, 26, 54, 55, 56, 23, + 37, 37, 26, 26, 28, 29, 24, 38, 54, 4, + 5, 29, 31, 32, 35, 36, 43, 45, 48, 51, + 56, 57, 62, 63, 25, 29, 30, 41, 49, 51, + 25, 13, 25, 25, 39, 46, 24, 35, 58, 49, + 9, 10, 11, 12, 27, 49, 49, 49, 50, 22, + 25, 29, 30, 40, 41, 42, 39, 29, 59, 26, + 49, 49, 49, 49, 26, 27, 28, 26, 40, 40, + 20, 21, 26, 14, 15, 16, 17, 18, 19, 37, + 47, 60, 28, 61, 27, 50, 26, 40, 40, 29, + 41, 41, 41, 41, 41, 41, 3, 37, 13, 59, + 27, 44, 49, 61, 37 +}; + +/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr1[] = +{ + 0, 33, 34, 34, 35, 35, 36, 36, 36, 36, + 36, 36, 36, 37, 38, 37, 39, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, + 41, 42, 44, 43, 43, 46, 47, 45, 48, 49, + 49, 49, 49, 49, 49, 49, 50, 50, 51, 52, + 52, 53, 53, 53, 54, 54, 55, 56, 56, 58, + 57, 59, 60, 59, 61, 61, 62, 63 +}; + +/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 1, 2, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 2, 0, 4, 3, 1, 1, 3, + 3, 3, 3, 3, 3, 3, 2, 3, 3, 1, + 1, 0, 0, 7, 4, 0, 0, 5, 4, 1, + 1, 3, 3, 3, 3, 3, 1, 3, 4, 4, + 4, 2, 3, 3, 1, 3, 2, 1, 1, 0, + 5, 1, 0, 4, 3, 0, 3, 5 +}; + + +enum { YYENOMEM = -2 }; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab +#define YYNOMEM goto yyexhaustedlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + + + + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Kind, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YY_USE (yyoutput); + if (!yyvaluep) + return; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); + + yy_symbol_value_print (yyo, yykind, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)]); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +/* Context of a parse error. */ +typedef struct +{ + yy_state_t *yyssp; + yysymbol_kind_t yytoken; +} yypcontext_t; + +/* Put in YYARG at most YYARGN of the expected tokens given the + current YYCTX, and return the number of tokens stored in YYARG. If + YYARG is null, return the number of expected tokens (guaranteed to + be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. + Return 0 if there are more than YYARGN expected tokens, yet fill + YYARG up to YYARGN. */ +static int +yypcontext_expected_tokens (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) +{ + /* Actual size of YYARG. */ + int yycount = 0; + int yyn = yypact[+*yyctx->yyssp]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (!yyarg) + ++yycount; + else if (yycount == yyargn) + return 0; + else + yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); + } + } + if (yyarg && yycount == 0 && 0 < yyargn) + yyarg[0] = YYSYMBOL_YYEMPTY; + return yycount; +} + + + + +#ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) +# else +/* Return the length of YYSTR. */ +static YYPTRDIFF_T +yystrlen (const char *yystr) +{ + YYPTRDIFF_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +#endif + +#ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +#endif + + + +static int +yy_syntax_error_arguments (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) +{ + /* Actual size of YYARG. */ + int yycount = 0; + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yyctx->yytoken != YYSYMBOL_YYEMPTY) + { + int yyn; + if (yyarg) + yyarg[yycount] = yyctx->yytoken; + ++yycount; + yyn = yypcontext_expected_tokens (yyctx, + yyarg ? yyarg + 1 : yyarg, yyargn - 1); + if (yyn == YYENOMEM) + return YYENOMEM; + else + yycount += yyn; + } + return yycount; +} + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, + const yypcontext_t *yyctx) +{ + enum { YYARGS_MAX = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ + yysymbol_kind_t yyarg[YYARGS_MAX]; + /* Cumulated lengths of YYARG. */ + YYPTRDIFF_T yysize = 0; + + /* Actual size of YYARG. */ + int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); + if (yycount == YYENOMEM) + return YYENOMEM; + + switch (yycount) + { +#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +#undef YYCASE_ + } + + /* Compute error message size. Don't count the "%s"s, but reserve + room for the terminator. */ + yysize = yystrlen (yyformat) - 2 * yycount + 1; + { + int yyi; + for (yyi = 0; yyi < yycount; ++yyi) + { + YYPTRDIFF_T yysize1 + = yysize + yystrlen (yysymbol_name (yyarg[yyi])); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return YYENOMEM; + } + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return -1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp = yystpcpy (yyp, yysymbol_name (yyarg[yyi++])); + yyformat += 2; + } + else + { + ++yyp; + ++yyformat; + } + } + return 0; +} + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep) +{ + YY_USE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/* Lookahead token kind. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yy_state_fast_t yystate = 0; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus = 0; + + /* Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; + + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; + + int yyn; + /* The return value of yyparse. */ + int yyresult; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yychar = YYEMPTY; /* Cause a token to be read. */ + + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + YYNOMEM; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + YYNOMEM; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + YYNOMEM; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token\n")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 14: /* $@1: %empty */ +#line 79 "yacc.y" + {increaseDepth();} +#line 1436 "yacc.tab.c" + break; + + case 15: /* InnerBlock: tLBRACE $@1 Lines tRBRACE */ +#line 79 "yacc.y" + {decreaseDepth();} +#line 1442 "yacc.tab.c" + break; + + case 16: /* Condition: tLPAR ConditionalExpression tRPAR */ +#line 83 "yacc.y" + {(yyval.addr) = (yyvsp[-1].addr);} +#line 1448 "yacc.tab.c" + break; + + case 17: /* ConditionalExpression: tID */ +#line 86 "yacc.y" + { (yyval.addr) = getOffset((yyvsp[0].str));} +#line 1454 "yacc.tab.c" + break; + + case 18: /* ConditionalExpression: tNB */ +#line 87 "yacc.y" + {(yyval.addr) = operation_afc_nb_tmp((yyvsp[0].nbInt));} +#line 1460 "yacc.tab.c" + break; + + case 19: /* ConditionalExpression: tLPAR ConditionalExpression tRPAR */ +#line 88 "yacc.y" + {(yyval.addr) = (yyvsp[-1].addr);} +#line 1466 "yacc.tab.c" + break; + + case 20: /* ConditionalExpression: NbOrVariable tLE NbOrVariable */ +#line 89 "yacc.y" + {(yyval.addr) = cond_not(cond_sup((yyvsp[-2].addr), (yyvsp[0].addr)));} +#line 1472 "yacc.tab.c" + break; + + case 21: /* ConditionalExpression: NbOrVariable tGE NbOrVariable */ +#line 90 "yacc.y" + {(yyval.addr) = cond_not(cond_inf((yyvsp[-2].addr), (yyvsp[0].addr)));} +#line 1478 "yacc.tab.c" + break; + + case 22: /* ConditionalExpression: NbOrVariable tEQ NbOrVariable */ +#line 91 "yacc.y" + {(yyval.addr) = cond_eq((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1484 "yacc.tab.c" + break; + + case 23: /* ConditionalExpression: NbOrVariable tNE NbOrVariable */ +#line 92 "yacc.y" + {(yyval.addr) = cond_not(cond_eq((yyvsp[-2].addr), (yyvsp[0].addr)));} +#line 1490 "yacc.tab.c" + break; + + case 24: /* ConditionalExpression: NbOrVariable tLT NbOrVariable */ +#line 93 "yacc.y" + {(yyval.addr) = cond_inf((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1496 "yacc.tab.c" + break; + + case 25: /* ConditionalExpression: NbOrVariable tGT NbOrVariable */ +#line 94 "yacc.y" + {(yyval.addr) = cond_sup((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1502 "yacc.tab.c" + break; + + case 26: /* ConditionalExpression: tNOT ConditionalExpression */ +#line 95 "yacc.y" + {(yyval.addr) = cond_not((yyvsp[0].addr));} +#line 1508 "yacc.tab.c" + break; + + case 27: /* ConditionalExpression: ConditionalExpression tOR ConditionalExpression */ +#line 96 "yacc.y" + {(yyval.addr) = cond_or((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1514 "yacc.tab.c" + break; + + case 28: /* ConditionalExpression: ConditionalExpression tAND ConditionalExpression */ +#line 97 "yacc.y" + {(yyval.addr) = cond_and((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1520 "yacc.tab.c" + break; + + case 29: /* NbOrVariable: tID */ +#line 102 "yacc.y" + { (yyval.addr) = getOffset((yyvsp[0].str));} +#line 1526 "yacc.tab.c" + break; + + case 30: /* NbOrVariable: tNB */ +#line 103 "yacc.y" + {(yyval.addr) = operation_afc_nb_tmp((yyvsp[0].nbInt));} +#line 1532 "yacc.tab.c" + break; + + case 31: /* IfStatement1: %empty */ +#line 114 "yacc.y" + { + int ligne =getCurrentLineNumber(); addLine("JMF"); (yyval.nbInt) = ligne ; + } +#line 1540 "yacc.tab.c" + break; + + case 32: /* $@2: %empty */ +#line 118 "yacc.y" + { + setConditionAddr((yyvsp[-2].nbInt),(yyvsp[-3].addr)); int current = getCurrentLineNumber(); printf("current Line %d", current); addLine("JMP"); (yyvsp[-4].nbInt) = current; setJumpLine((yyvsp[-2].nbInt), current+1); +} +#line 1548 "yacc.tab.c" + break; + + case 33: /* IfStatement: tIF Condition IfStatement1 InnerBlock tELSE $@2 InnerBlock */ +#line 120 "yacc.y" + { + int current = getCurrentLineNumber() ; printf("%d, %d",(yyvsp[-6].nbInt), current);setJumpLine((yyvsp[-6].nbInt), current); +} +#line 1556 "yacc.tab.c" + break; + + case 34: /* IfStatement: tIF Condition IfStatement1 InnerBlock */ +#line 123 "yacc.y" + { + setConditionAddr((yyvsp[-1].nbInt),(yyvsp[-2].addr)); int current = getCurrentLineNumber(); printf("current Line %d", current); setJumpLine((yyvsp[-1].nbInt), current); +} +#line 1564 "yacc.tab.c" + break; + + case 35: /* $@3: %empty */ +#line 127 "yacc.y" + { + (yyvsp[0].nbInt) = getCurrentLineNumber(); +} +#line 1572 "yacc.tab.c" + break; + + case 36: /* $@4: %empty */ +#line 129 "yacc.y" + { + int current = getCurrentLineNumber(); + addLine("JMF"); + setConditionAddr(current,(yyvsp[0].addr)); + whileJumpAddr = current; + suppressCONDElements(); +} +#line 1584 "yacc.tab.c" + break; + + case 37: /* WhileStatement: tWHILE $@3 Condition $@4 InnerBlock */ +#line 135 "yacc.y" + { + addLine("JMP"); + int current = getCurrentLineNumber(); + setJumpLine(whileJumpAddr, current); + setJumpLine(current-1, (yyvsp[-4].nbInt)); +} +#line 1595 "yacc.tab.c" + break; + + case 38: /* Assignment: tID tASSIGN Expression tSEMI */ +#line 142 "yacc.y" + { + setInit((yyvsp[-3].str)); operation_copy(getOffset((yyvsp[-3].str)),(yyvsp[-1].addr)); suppressTempINTElements(); + } +#line 1603 "yacc.tab.c" + break; + + case 39: /* Expression: NbOrVariable */ +#line 147 "yacc.y" + {(yyval.addr) = (yyvsp[0].addr);} +#line 1609 "yacc.tab.c" + break; + + case 40: /* Expression: FunctionCall */ +#line 148 "yacc.y" + {(yyval.addr) = 0;} +#line 1615 "yacc.tab.c" + break; + + case 41: /* Expression: tLPAR Expression tRPAR */ +#line 149 "yacc.y" + {(yyval.addr) = (yyvsp[-1].addr);} +#line 1621 "yacc.tab.c" + break; + + case 42: /* Expression: Expression tADD Expression */ +#line 153 "yacc.y" + {(yyval.addr) = operation_add((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1627 "yacc.tab.c" + break; + + case 43: /* Expression: Expression tSUB Expression */ +#line 154 "yacc.y" + {(yyval.addr) = operation_sub((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1633 "yacc.tab.c" + break; + + case 44: /* Expression: Expression tMUL Expression */ +#line 155 "yacc.y" + {(yyval.addr) = operation_mul((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1639 "yacc.tab.c" + break; + + case 45: /* Expression: Expression tDIV Expression */ +#line 156 "yacc.y" + {(yyval.addr) = operation_divInt((yyvsp[-2].addr), (yyvsp[0].addr));} +#line 1645 "yacc.tab.c" + break; + + case 49: /* FunctionDef: Type tID FunctionParams InnerBlock */ +#line 164 "yacc.y" + {resetSymboltable();} +#line 1651 "yacc.tab.c" + break; + + case 50: /* FunctionDef: tVOID tID FunctionParams InnerBlock */ +#line 165 "yacc.y" + {resetSymboltable();} +#line 1657 "yacc.tab.c" + break; + + case 56: /* VarWithType: Type tID */ +#line 176 "yacc.y" + {addElement((yyvsp[0].str),(yyvsp[-1].type));setInit((yyvsp[0].str));} +#line 1663 "yacc.tab.c" + break; + + case 57: /* Type: tINT */ +#line 179 "yacc.y" + {(yyval.type) = INT;} +#line 1669 "yacc.tab.c" + break; + + case 58: /* Type: tFLOAT */ +#line 180 "yacc.y" + {(yyval.type) = FLOAT;} +#line 1675 "yacc.tab.c" + break; + + case 59: /* $@5: %empty */ +#line 183 "yacc.y" + { t = (yyvsp[0].type); } +#line 1681 "yacc.tab.c" + break; + + case 61: /* Declaration: tID */ +#line 185 "yacc.y" + {addElement((yyvsp[0].str), (enumVarType) t);} +#line 1687 "yacc.tab.c" + break; + + case 62: /* $@6: %empty */ +#line 186 "yacc.y" + {addElement((yyvsp[0].str), (enumVarType) t); setInit((yyvsp[0].str));} +#line 1693 "yacc.tab.c" + break; + + case 63: /* Declaration: tID $@6 tASSIGN Expression */ +#line 186 "yacc.y" + {operation_copy(getOffset((yyvsp[-3].str)),(yyvsp[0].addr)); suppressTempINTElements();} +#line 1699 "yacc.tab.c" + break; + + case 66: /* Return: tRETURN Expression tSEMI */ +#line 191 "yacc.y" + {} +#line 1705 "yacc.tab.c" + break; + + +#line 1709 "yacc.tab.c" + + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; + { + yypcontext_t yyctx + = {yyssp, yytoken}; + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == -1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = YY_CAST (char *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); + if (yymsg) + { + yysyntax_error_status + = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + yymsgp = yymsg; + } + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = YYENOMEM; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == YYENOMEM) + YYNOMEM; + } + } + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + ++yynerrs; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + /* Pop stack until we find a state that shifts the error token. */ + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + YY_ACCESSING_SYMBOL (yystate), yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturnlab; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturnlab; + + +/*-----------------------------------------------------------. +| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | +`-----------------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + goto yyreturnlab; + + +/*----------------------------------------------------------. +| yyreturnlab -- parsing is finished, clean up and return. | +`----------------------------------------------------------*/ +yyreturnlab: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + return yyresult; +} + +#line 195 "yacc.y" + + +void yyerror(const char *msg) { + fprintf(stderr, "\033[1m\033[31m[/!\\]\033[0m Error : %s\n", msg); + exit(1); +} + +int main(void) { + clearOp(); + initSymbolTable(); + initASMTable(); + yyparse(); + exportASMTable(); +} + // SI >> SC diff --git a/compilateur/yacc.tab.h b/compilateur/yacc.tab.h new file mode 100644 index 0000000..2b92763 --- /dev/null +++ b/compilateur/yacc.tab.h @@ -0,0 +1,120 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +#ifndef YY_YY_YACC_TAB_H_INCLUDED +# define YY_YY_YACC_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + tELSE = 258, /* tELSE */ + tRETURN = 259, /* tRETURN */ + tPRINT = 260, /* tPRINT */ + tFLOAT = 261, /* tFLOAT */ + tINT = 262, /* tINT */ + tVOID = 263, /* tVOID */ + tSUB = 264, /* tSUB */ + tADD = 265, /* tADD */ + tMUL = 266, /* tMUL */ + tDIV = 267, /* tDIV */ + tASSIGN = 268, /* tASSIGN */ + tLT = 269, /* tLT */ + tGT = 270, /* tGT */ + tNE = 271, /* tNE */ + tEQ = 272, /* tEQ */ + tGE = 273, /* tGE */ + tLE = 274, /* tLE */ + tAND = 275, /* tAND */ + tOR = 276, /* tOR */ + tNOT = 277, /* tNOT */ + tLBRACE = 278, /* tLBRACE */ + tRBRACE = 279, /* tRBRACE */ + tLPAR = 280, /* tLPAR */ + tRPAR = 281, /* tRPAR */ + tSEMI = 282, /* tSEMI */ + tCOMMA = 283, /* tCOMMA */ + tID = 284, /* tID */ + tNB = 285, /* tNB */ + tIF = 286, /* tIF */ + tWHILE = 287 /* tWHILE */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 22 "yacc.y" +char str[NAME_MAX_LENGTH]; int nbInt; int addr; enumVarType type; + +#line 99 "yacc.tab.h" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + + +int yyparse (void); + +/* "%code provides" blocks. */ +#line 17 "yacc.y" + +int yylex (void); +void yyerror (const char *); + +#line 119 "yacc.tab.h" + +#endif /* !YY_YY_YACC_TAB_H_INCLUDED */ diff --git a/compilateur/yacc.tab.o b/compilateur/yacc.tab.o new file mode 100644 index 0000000..3a81621 Binary files /dev/null and b/compilateur/yacc.tab.o differ diff --git a/compilateur/yacc.y b/compilateur/yacc.y new file mode 100644 index 0000000..626d227 --- /dev/null +++ b/compilateur/yacc.y @@ -0,0 +1,209 @@ +%define parse.error detailed + +%{ +#include +#include +#include "table.h" +#include "operations.h" +#include "blocs.h" +#include "asmTable.h" + +int t; +int labelWhileStart; +int labelWhileEnd; +int whileJumpAddr; +%} + +%code provides{ +int yylex (void); +void yyerror (const char *); +} + +%union {char str[NAME_MAX_LENGTH]; int nbInt; int addr; enumVarType type; } + /*loops keywords*/ +%token /*tWHILE tIF declared below*/ tELSE + /*reserved keywords*/ +%token tRETURN tPRINT + /*types : integers, floats or void*/ +%token tFLOAT tINT tVOID + /*operations, mul and div are precedent to sub and add*/ +%left tSUB tADD +%left tMUL tDIV + /*Assignment*/ +%left tASSIGN + /*comparisons*/ +%left tLT tGT tNE tEQ tGE tLE + /*boolean operators*/ +%left tAND tOR tNOT + /*syntaxic symbols*/ +%token tLBRACE tRBRACE tLPAR tRPAR tSEMI tCOMMA + + /*nametags and values*/ +%token tID +%token tNB + + + /* represents types with the values used in the table, see table.h */ +%type Type +%type Expression +%type ConditionalExpression +%type Declaration +%type NbOrVariable +%type IfStatement1 +%type Condition +%type InnerBlock + +%token tIF +%token tWHILE + +%start Program +%% + +Program : FunctionDef + | FunctionDef Program; + + /* Lines = Any line in the code that is not within an if/while statement*/ + Lines : Line + | Line Lines; + +Line : IfStatement + | WhileStatement + | Assignment + | Declarations + | FunctionCall + | Return + | Print; + +/*Innerblock = the inside of an if/else/while statement = { ... } or function = f(){...}*/ +InnerBlock : tLBRACE tRBRACE // a function or while loop can be empty cf GCC + | tLBRACE {increaseDepth();} Lines tRBRACE {decreaseDepth();}; + + +/*Condition = the evaluated boolean expression for an if or while = ( ... ) */ +Condition : tLPAR ConditionalExpression tRPAR {$$ = $2;}; + +/*ConditionalExpression = expression that evaluates to a boolean*/ +ConditionalExpression : tID { $$ = getOffset($1);} + | tNB {$$ = operation_afc_nb_tmp($1);} + | tLPAR ConditionalExpression tRPAR {$$ = $2;}// for cases like if((a or b) and (a or c)) where there are parenthesis inside + | NbOrVariable tLE NbOrVariable {$$ = cond_not(cond_sup($1, $3));} + | NbOrVariable tGE NbOrVariable {$$ = cond_not(cond_inf($1, $3));} + | NbOrVariable tEQ NbOrVariable {$$ = cond_eq($1, $3);} + | NbOrVariable tNE NbOrVariable {$$ = cond_not(cond_eq($1, $3));} + | NbOrVariable tLT NbOrVariable {$$ = cond_inf($1, $3);} + | NbOrVariable tGT NbOrVariable {$$ = cond_sup($1, $3);} + | tNOT ConditionalExpression {$$ = cond_not($2);} + | ConditionalExpression tOR ConditionalExpression {$$ = cond_or($1, $3);} + | ConditionalExpression tAND ConditionalExpression {$$ = cond_and($1, $3);}; + /*end of added bloat*/ + + +/*NbOrVariable is either a number or a variable of type int*/ +NbOrVariable : tID { $$ = getOffset($1);} + | tNB {$$ = operation_afc_nb_tmp($1);}; + + /*List of all numerical operators*/ + /* +NumericalOperator : tLE | tGE | tEQ | tNE | tLT | tGT; +*/ + + /*any arithmetic operation +Operation: tADD | tMUL | tSUB | tDIV; +*/ + +IfStatement1 : %empty { + int ligne =getCurrentLineNumber(); addLine("JMF"); $$ = ligne ; + }; + +IfStatement : tIF Condition IfStatement1 InnerBlock tELSE { + setConditionAddr($3,$2); int current = getCurrentLineNumber(); printf("current Line %d", current); addLine("JMP"); $1 = current; setJumpLine($3, current+1); +} InnerBlock { + int current = getCurrentLineNumber() ; printf("%d, %d",$1, current);setJumpLine($1, current); +} + | tIF Condition IfStatement1 InnerBlock { + setConditionAddr($3,$2); int current = getCurrentLineNumber(); printf("current Line %d", current); setJumpLine($3, current); +}; + +WhileStatement : tWHILE { + $1 = getCurrentLineNumber(); +} Condition { + int current = getCurrentLineNumber(); + addLine("JMF"); + setConditionAddr(current,$3); + whileJumpAddr = current; + suppressCONDElements(); +} InnerBlock { + addLine("JMP"); + int current = getCurrentLineNumber(); + setJumpLine(whileJumpAddr, current); + setJumpLine(current-1, $1); +}; + +Assignment : tID tASSIGN Expression tSEMI { + setInit($1); operation_copy(getOffset($1),$3); suppressTempINTElements(); + }; + + /*Expression operation applied on variables or values*/ +Expression : NbOrVariable {$$ = $1;} + | FunctionCall{$$ = 0;} // TODO : wait untile functions are implemented + | tLPAR Expression tRPAR {$$ = $2;} + /* replaced by the four following lines + //| Expression Operation Expression + */ + | Expression tADD Expression {$$ = operation_add($1, $3);} + | Expression tSUB Expression {$$ = operation_sub($1, $3);} + | Expression tMUL Expression {$$ = operation_mul($1, $3);} + | Expression tDIV Expression {$$ = operation_divInt($1, $3);}; + /*end of added bloat*/ + +Expressions : Expression + | Expression tCOMMA Expressions; + +FunctionCall : tID tLPAR Expressions tRPAR; + +FunctionDef : Type tID FunctionParams InnerBlock {resetSymboltable();} + | tVOID tID FunctionParams InnerBlock {resetSymboltable();}; + + /*FunctionParams = the parameters of a function*/ +FunctionParams : tLPAR tRPAR + | tLPAR tVOID tRPAR + | tLPAR VarsWithType tRPAR + +VarsWithType : VarWithType + | VarWithType tCOMMA VarsWithType; + + /*VarWithType = a variable associated to its type = int a*/ +VarWithType : Type tID {addElement($2,$1);setInit($2);}; + + /*the return type or argument type*/ +Type : tINT {$$ = INT;} + | tFLOAT {$$ = FLOAT;}; + + +Declarations : Type { t = $1; } Declaration Declarations1 tSEMI ; + +Declaration : tID {addElement($1, (enumVarType) t);} + | tID {addElement($1, (enumVarType) t); setInit($1);} tASSIGN Expression {operation_copy(getOffset($1),$4); suppressTempINTElements();} ; + +Declarations1 : tCOMMA Declaration Declarations1 | %empty ; + + +Return : tRETURN Expression tSEMI {}; + +Print : tPRINT tLPAR Expression tRPAR tSEMI; + +%% + +void yyerror(const char *msg) { + fprintf(stderr, "\033[1m\033[31m[/!\\]\033[0m Error : %s\n", msg); + exit(1); +} + +int main(void) { + clearOp(); + initSymbolTable(); + initASMTable(); + yyparse(); + exportASMTable(); +} + // SI >> SC diff --git a/cross-Compiler/cross-compiler.py b/cross-Compiler/cross-compiler.py new file mode 100644 index 0000000..d724fa1 --- /dev/null +++ b/cross-Compiler/cross-compiler.py @@ -0,0 +1,182 @@ +import re + +opToBinOP = { + "ADD": "01", + "MUL": "02", + "SUB": "03", + "DIV": "04", + "COP": "05", + "AFC": "06", + "LOAD": "07", + "STORE": "08", + "INF": "09", + "SUP": "0A", + "EQ": "0B", + "NOT": "0C", + "AND": "0D", + "OR": "0E", + "JMP": "0F", + "JMF": "10", + "CAL": "11", + "RET": "12", + "PRI": "13", + "NOP": "FF" +} + + +def output(s, num, oneline=False): + fileOutput = open(f'asm{num}', 'w') + if oneline: + fileOutput.write(s) + else : + fileOutput.write("\n".join(s)) + fileOutput.close() + + +def convertToRegister(s): + l = [] + + if not re.match(r"\d_LABEL", s[0]): + optionalFlag = "" + incr = 0 + op = s[0] + else: + optionalFlag = s[0] + " " + incr = 1 + op = s[1] + + match op: + case "ADD": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("ADD 0 0 1") + l.append("STORE " + s[1 + incr] + " 0") + case "MUL": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("MUL 0 0 1") + l.append("STORE " + s[1 + incr] + " 0") + case "SUB": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("SUB 0 0 1") + l.append("STORE " + s[1 + incr] + " 0") + case "DIV_INT": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("DIV 0 0 1") + l.append("STORE " + s[1 + incr] + " 0") + case "COP": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("STORE " + s[1 + incr] + " 0") + case "AFC": + l.append(optionalFlag + "AFC 0 " + s[2 + incr]) + l.append("STORE " + s[1 + incr] + " 0") + case "JMP": + l.append(" ".join(s)) + case "JMF": + if len(s) == 3: + l.append(" ".join(s)) + else : + l.append(s[0]+ " 0 " + s[1]) + case "INF": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("INF 2 0 1") + l.append("STORE " + s[1 + incr] + " 2") + case "SUP": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("SUP 2 1 0") + l.append("STORE " + s[1 + incr] + " 2") + case "EQ": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("EQ 2 1 0") + l.append("STORE " + s[1 + incr] + " 2") + case "PRI": + l.append(optionalFlag + "PRI " + s[2 + incr]) + case "AND": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("AND 2 0 1") + l.append("STORE " + s[1 + incr] + " 2") + case "OR": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("LOAD 1 " + s[3 + incr]) + l.append("OR 2 0 1") + l.append("STORE " + s[1 + incr] + " 2") + case "NOT": + l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) + l.append("NOT 2 0") + l.append("STORE " + s[1 + incr] + " 2") + case default: + l.append(" ".join(s)) + + """ R2 will contain the information whether to jump or not""" + + return l + + +totalLine = 0 +labelCount = 0 # used to create a new label each time + +fileInput = open("asm", "r") +ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines())) +fileInput.close() + +# added to prevent problems when cross compiling some code representing a jump to after the last line +ASMLines.append("NOP") + +ASMLinesLabel = ASMLines[:] # will contain at the end of the first loop the code with labels inserted +ASMLinesRegister = [] # will contain at the end of the 2nd loop the registry-based code with labels +ASMLinesFinal = [] # will contain the output, register-based, code + +for i, l in enumerate(ASMLines): + items = l.split(" ") + if items[0] in ["JMP", "JMF"]: + lineToJumpTo = int(items[-1]) + if re.match(r"\d_LABEL .*", ASMLinesLabel[lineToJumpTo]): + ASMLinesLabel[i] = " ".join(ASMLines[i].split()[:-1] + [ASMLinesLabel[lineToJumpTo].split()[0]]) + else: + ASMLinesLabel[lineToJumpTo] = f"{labelCount}_LABEL " + ASMLines[lineToJumpTo] + ASMLinesLabel[i] = " ".join(ASMLinesLabel[i].split()[:-1] + [f"{labelCount}_LABEL"]) + labelCount += 1 +print("labels : ", ASMLinesLabel) + +for i, l in enumerate(ASMLinesLabel): + ASMLinesRegister.extend(convertToRegister(l.split())) +print("regs : ", ASMLinesRegister) + +labels = {} +for i, l in enumerate(ASMLinesRegister): + if re.match(r"\d_LABEL .*", l): + labels[l.split()[0]] = i + ASMLinesRegister[i] = " ".join(ASMLinesRegister[i].split()[1:]) +print(ASMLinesRegister) + +for i, l in enumerate(ASMLinesRegister): + label = re.match(r"\d_LABEL", l.split()[-1]) + if label: + ASMLinesFinal.append(" ".join(l.split()[:-1] + [str(labels[label[0]])])) + else: + ASMLinesFinal.append(l) + +print(ASMLinesFinal) +output(ASMLinesFinal, 2) + +lines = [] +for i, l in enumerate(ASMLinesFinal): + arr = l.split() + while len(arr) < 4: + arr.append(0) + lines.append(f"(x\"{opToBinOP[arr[0]]}{int(arr[1]):02X}{int(arr[2]):02X}{int(arr[3]):02X}\")") +ASMLinesConverted = "(" + ",".join(lines) + ",others => (x\"ff000000\"))" +print("converted to VHDL-friendly format : " + ASMLinesConverted) +output(ASMLinesConverted, 3, True) + + +""" Used to generate the beautiful table in the report +for i in range(10): + print(f"{ASMLines[i]} & {ASMLinesFinal[i]} & {ASMLinesConverted.split(',')[i]} \\\\") +""" diff --git a/interpreter/graph_interpreter.py b/interpreter/graph_interpreter.py new file mode 100644 index 0000000..b3384bb --- /dev/null +++ b/interpreter/graph_interpreter.py @@ -0,0 +1,140 @@ +import sys + + +try: + from textual.color import Color + from textual import events + from textual.app import App, ComposeResult + from textual.containers import Container, VerticalScroll + from textual.widgets import Footer, Header, Static +except: + print("please install textual and rich !") + + +def getLinesToShow(ip, lines): + if ip > 1 and ip + 2 < len(lines): + l= lines[ip - 2: ip + 3] + l[2] = "> " + l[2] + " <" + elif ip <= 1: + l= lines[0: 5] + l[ip] = "> " + l[ip] + " <" + else: + l= lines[-5:] + l[ip-len(lines)] = "> " + l[ip-len(lines)] + " <" + return l + + +def update_interpreter(self): + global ip + global ASMLines + global dataMem + if "NOP" not in ASMLines[ip]: + incr = 1 + currLine = ASMLines[ip].split() + match currLine[0]: + case "ADD": + dataMem[currLine[1]] = dataMem[currLine[2]] + dataMem[currLine[3]] + case "MUL": + dataMem[currLine[1]] = dataMem[currLine[2]] * dataMem[currLine[3]] + case "SUB": + dataMem[currLine[1]] = dataMem[currLine[2]] - dataMem[currLine[3]] + case "DIV": + dataMem[currLine[1]] = dataMem[currLine[2]] / dataMem[currLine[3]] + case "COP": + dataMem[currLine[1]] = dataMem[currLine[2]] + case "AFC": + dataMem[currLine[1]] = int(currLine[2]) + case "SUP": + dataMem[currLine[1]] = dataMem[currLine[2]] > dataMem[currLine[3]] + case "EQ": + dataMem[currLine[1]] = dataMem[currLine[2]] == dataMem[currLine[3]] + case "NOT": + dataMem[currLine[1]] = not dataMem[currLine[2]] + case "INF": + dataMem[currLine[1]] = dataMem[currLine[2]] < dataMem[currLine[3]] + case "AND": + dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]] + case "OR": + dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]] + case "JMP": + ip = int(currLine[1]) + incr = 0 + case "JMF": + if not dataMem[currLine[1]]: + incr = 0 + ip = int(currLine[2]) + print(ip) + case "CAL": + pass + case "RET": + pass + case "PRI": + pass + case default: + pass + print(ASMLines[ip], ", ".join([f"{i}:{dataMem.get(i)}" for i in dataMem])) + ip += incr + else: + cont = self.query_one("#cont", Container) + cont.styles.background = Color.parse("#151E3D") + + code = self.query_one("#code", Static) + code.update(" ") + +class codeLines(Static): + """one line of assembly code""" + def update_code(self, line) -> None: + self.update(line) +class registers(Static): + """one line of assembly code""" + def update_regs(self, line) -> None: + self.update(line) + + +class interpreter(App): + """A Textual app to see your asm code run !.""" + TITLE = "A Textual app to see your asm code run !." + CSS_PATH = "style.css" + BINDINGS = [ + ("q", "quit", "Quit"), + ] + + def compose(self) -> ComposeResult: + """Compose our UI.""" + path = "./" if len(sys.argv) < 2 else sys.argv[1] + yield Header() + with Container(id="cont"): + with VerticalScroll(id="code-view"): + yield codeLines("\n".join(getLinesToShow(ip, ASMLines)),id="code", expand=True) + yield registers(id="regs", expand=True) + yield Footer() + + def on_key(self, event: events.Key) -> None: + code = self.query_one("#code", Static) + regs = self.query_one("#regs", Static) + update_interpreter(self) + + global ip, ASMLines + code.update_code("\n".join(getLinesToShow(ip, ASMLines))) + l = [] + for i in range(max([int(i)+1 for i in dataMem.keys()])): + if str(i) in dataMem.keys(): + l.append([i, dataMem[str(i)]]) + + regs.update_regs("\n".join([f"@{k[0]} : {k[1]}" for k in l])) + +if __name__ == "__main__": + + fileInput = open("asm", "r") + global ASMLines + ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines())) + fileInput.close() + ASMLines.append("NOP") + + global dataMem + dataMem = {} + + global ip + ip = 0 + + interpreter().run() diff --git a/interpreter/interpreter.old.py b/interpreter/interpreter.old.py new file mode 100644 index 0000000..e1fa4fc --- /dev/null +++ b/interpreter/interpreter.old.py @@ -0,0 +1,53 @@ + +fileInput = open("asm", "r") +ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines())) +fileInput.close() + +ASMLines.append("NOP") +dataMem = {} +ip = 0 +while ip < len(ASMLines): + incr = 1 + currLine = ASMLines[ip].split() + match currLine[0]: + case "ADD": + dataMem[currLine[1]] = dataMem[currLine[2]] + dataMem[currLine[3]] + case "MUL": + dataMem[currLine[1]] = dataMem[currLine[2]] * dataMem[currLine[3]] + case "SUB": + dataMem[currLine[1]] = dataMem[currLine[2]] - dataMem[currLine[3]] + case "DIV": + dataMem[currLine[1]] = dataMem[currLine[2]] / dataMem[currLine[3]] + case "COP": + dataMem[currLine[1]] = dataMem[currLine[2]] + case "AFC": + dataMem[currLine[1]] = int(currLine[2]) + case "SUP": + dataMem[currLine[1]] = dataMem[currLine[2]] > dataMem[currLine[3]] + case "EQ": + dataMem[currLine[1]] = dataMem[currLine[2]] == dataMem[currLine[3]] + case "NOT": + dataMem[currLine[1]] = not dataMem[currLine[2]] + case "INF": + dataMem[currLine[1]] = dataMem[currLine[2]] < dataMem[currLine[3]] + case "AND": + dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]] + case "OR": + dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]] + case "JMP": + ip = int(currLine[1]) + incr = 0 + case "JMF": + if not dataMem[currLine[1]]: + incr = 0 + ip = int(currLine[2]) + case "CAL": + pass + case "RET": + pass + case "PRI": + pass + case default: + pass + print(ASMLines[ip], ", ".join([f"{i}:{dataMem.get(i)}" for i in dataMem])) + ip += incr \ No newline at end of file diff --git a/interpreter/interpreter.py b/interpreter/interpreter.py new file mode 100644 index 0000000..192e619 --- /dev/null +++ b/interpreter/interpreter.py @@ -0,0 +1,61 @@ +from rich.console import Console +from rich.table import Table +table = Table() + +table.add_column("Operation", justify="left", style="red", no_wrap=True) +table.add_column("Register State", justify="center", style="green") + +fileInput = open("asm", "r") +ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines())) +fileInput.close() +ASMLines.append("NOP") + +dataMem = {} +ip = 0 +while ip < len(ASMLines): + incr = 1 + currLine = ASMLines[ip].split() + match currLine[0]: + case "ADD": + dataMem[currLine[1]] = dataMem[currLine[2]] + dataMem[currLine[3]] + case "MUL": + dataMem[currLine[1]] = dataMem[currLine[2]] * dataMem[currLine[3]] + case "SUB": + dataMem[currLine[1]] = dataMem[currLine[2]] - dataMem[currLine[3]] + case "DIV": + dataMem[currLine[1]] = dataMem[currLine[2]] / dataMem[currLine[3]] + case "COP": + dataMem[currLine[1]] = dataMem[currLine[2]] + case "AFC": + dataMem[currLine[1]] = int(currLine[2]) + case "SUP": + dataMem[currLine[1]] = dataMem[currLine[2]] > dataMem[currLine[3]] + case "EQ": + dataMem[currLine[1]] = dataMem[currLine[2]] == dataMem[currLine[3]] + case "NOT": + dataMem[currLine[1]] = not dataMem[currLine[2]] + case "INF": + dataMem[currLine[1]] = dataMem[currLine[2]] < dataMem[currLine[3]] + case "AND": + dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]] + case "OR": + dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]] + case "JMP": + ip = int(currLine[1]) + incr = 0 + case "JMF": + if not dataMem[currLine[1]]: + incr = 0 + ip = int(currLine[2]) + case "CAL": + pass + case "RET": + pass + case "PRI": + pass + case default: + pass + table.add_row(ASMLines[ip], ", ".join([f"{i}:{dataMem.get(i)}" for i in dataMem])) + ip += incr +console = Console() +console.print(table) diff --git a/interpreter/style.css b/interpreter/style.css new file mode 100644 index 0000000..0eb8a07 --- /dev/null +++ b/interpreter/style.css @@ -0,0 +1,7 @@ + +#code { + overflow: auto scroll; + text-align: center; + padding-top: 3; + width: 100%; +} \ No newline at end of file diff --git a/out b/out new file mode 100755 index 0000000..e6d65b3 Binary files /dev/null and b/out differ diff --git a/tests/testFile b/tests/testFile new file mode 100644 index 0000000..aa73e71 --- /dev/null +++ b/tests/testFile @@ -0,0 +1,9 @@ +int main() { + int a; + a = 5; + if (a != 8) { + while(a < 20){ + a = a+2; + } + } +} diff --git a/tests/testFile_fibo b/tests/testFile_fibo new file mode 100644 index 0000000..b79b1bd --- /dev/null +++ b/tests/testFile_fibo @@ -0,0 +1,20 @@ +int main() { + int i, n, nextTerm, t1, t2; + + i = 0; + n = 20; // put here the number you want ! + + t1 = 0; + t2 = 1; + + nextTerm = t1 + t2; + + n = n - 3; // cause nextTerm already contains the 3rd term + while (i <= n){ + t1 = t2; + t2 = nextTerm; + nextTerm = t1 + t2; + i = i+1; + } +} + diff --git a/tests/testFile_no_jmp b/tests/testFile_no_jmp new file mode 100644 index 0000000..d572de9 --- /dev/null +++ b/tests/testFile_no_jmp @@ -0,0 +1,9 @@ +int main(){ + int a, d; + int b, c = 2; + b = a; + a = b +2; + a = c; + a = 5; + c = 19 + 2 - (5 * a + 8) * 2; +} diff --git a/tests/testFile_while b/tests/testFile_while new file mode 100644 index 0000000..585c578 --- /dev/null +++ b/tests/testFile_while @@ -0,0 +1,13 @@ +int compute(int a, int d) { + int b, c = a + d * 5; + b = a; + while(!(!(!(!((a > b)))))){ + if (a == b){ + a = b; + } else { + a = c; + } + } + a=5; +} + diff --git a/vhdl/ALU.vhd b/vhdl/ALU.vhd new file mode 100644 index 0000000..8e96a44 --- /dev/null +++ b/vhdl/ALU.vhd @@ -0,0 +1,92 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12.05.2023 16:14:24 +-- Design Name: +-- Module Name: ALU - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +-- use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity ALU is + Port ( A : in STD_LOGIC_VECTOR (7 downto 0); + B : in STD_LOGIC_VECTOR (7 downto 0); + Ctrl_Alu : in STD_LOGIC_VECTOR (7 downto 0); + S : out STD_LOGIC_VECTOR (7 downto 0); + N : out STD_LOGIC; + O : out STD_LOGIC; + Z : out STD_LOGIC; + C : out STD_LOGIC; + JumpFlagOut : out STD_LOGIC; -- 0 false 1 true + JumpFlagIn : in STD_LOGIC + ); +end ALU; + +-- Instruction code + -- ADD x"01" + -- MUL x"02" + -- SUB x"03" + -- DIV x"04" + -- INF x"09" + -- SUP x"0A" + -- EQ x"0B" + -- NOT x"0C" + -- AND x"0D" + -- OR x"0E" + -- XOR x"0F" + + +architecture Behavioral of ALU is + signal res : STD_LOGIC_VECTOR(15 downto 0):= x"0000"; + signal flag : STD_LOGIC := '0'; +begin + process(A, B, Ctrl_Alu) + begin + N <= '0'; + O <= '0'; + Z <= '0'; + C <= '0'; + flag <= JumpFlagIn; + case Ctrl_Alu is + when x"01" => res <= (x"00" & A) + (x"00" & B) ; if (((x"00" & A) + (x"00" & B)) > 255) then C <= '1'; elsif (A+B = 0) then Z <= '1'; end if; -- ADD + when x"02" => res <= A * B; if (A * B > 255) then O <= '1'; elsif A * B = 0 then Z <= '1'; end if; -- MUL + when x"03" => res <= (x"00" & A) - (x"00" & B) ; if (B > A) then N <= '1'; elsif (B = A) then Z <= '1'; end if; -- SUB + when x"04" => if (B /= 0) then res <= (x"00" & std_logic_vector(to_unsigned(to_integer(unsigned(A)) / to_integer(unsigned(B)),8))); else res <= x"0000"; end if; -- DIV + when x"09" => if A < B then res <= x"0001"; flag <= '1'; else res <= x"0000"; flag <= '0'; end if; + when x"0A" => if A > B then res <= x"0001"; flag <= '1'; else res <= x"0000"; flag <= '0'; end if; + when x"0B" => if A = B then res <= x"0001"; flag <= '1'; else res <= x"0000"; flag <= '0'; end if; + when x"0C" => if A > 0 then res <= x"0001"; flag <= '1'; else res <= x"0000"; flag <= '0'; end if; + when x"0D" => if (A > 0 and B > 0) then res <= x"0001" ; flag <= '1'; else res <= x"0000"; flag <= '0'; end if; + when x"0E" => if (A > 0 or B > 0) then res <= x"0001" ; flag <= '1'; else res <= x"0000"; flag <= '0'; end if; + when x"0F" => if ((A > 0 and B = 0) or (A = 0 and B >0)) then res <= x"0001" ; flag <= '1'; else res <= x"0000"; flag <= '0'; end if; + when others => res <= x"0000"; + end case; + end process; + JumpFlagOut <= flag; + S <= res(7 downto 0); +end Behavioral; diff --git a/vhdl/AleaControler.vhd b/vhdl/AleaControler.vhd new file mode 100644 index 0000000..c6e728e --- /dev/null +++ b/vhdl/AleaControler.vhd @@ -0,0 +1,77 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.all; + +-- Instruction coEX + -- ADD 00000001 + -- MUL 00000010 + -- SUB 00000011 + -- DIV 00000100 + -- COP 00000101 + -- AFC 00000110 + -- LOAD 00000111 + -- STORE 00001000 + -- INF 00001001 + -- SUP 00001010 + -- EQ 00001011 + -- NOT 00001100 + -- AND 00001101 + -- OR 00001110 + -- NOP 11111111 + + + +-- when the just entered instruction causes a problem with an instruction already in the EX or Mem stage (a write-Back stage would not cause any harm) we: + -- we freeze IP on the current instruction + -- we insert NOPs in the LI_DI OP while there is a conflict in order to let the problematic instruction finish + +entity AleaControler is + Port ( + -- get the current op and variables from the 3 pipelines stages that can interract + Op_DI, Op_EX, Op_Mem, Op_Re : in STD_LOGIC_VECTOR (7 downto 0); + A_EX, A_Mem, A_Re : in STD_LOGIC_VECTOR (7 downto 0); + B_DI : in STD_LOGIC_VECTOR (7 downto 0); + C_DI : in STD_LOGIC_VECTOR (7 downto 0); + + CNTRL : out STD_LOGIC); +end AleaControler; + + +architecture Behavioral of AleaControler is + signal alea_DI_EX, alea_DI_MEM: STD_LOGIC; + signal is_LI_arithmetic, is_DI_arithmetic: STD_LOGIC; +begin + CNTRL <= -- either a problem between the 1st and 2nd or 1st and 3rd + '1' when + -- read after write : Op1 other than STORE/NOP/JMP/JMF, op2 other than AFC/NOP/JMP/JMF, R(write) = R(read) + ( + -- check Op1 & Op2 + ((OP_DI /= x"06" and OP_DI /= x"ff" and OP_Di /= x"0F" and OP_DI /= x"10") and (Op_EX /= x"08" and Op_EX /= x"ff" and Op_EX /= x"0f" and Op_EX /= x"10")) and + + -- check Registers are the same + ((A_Ex = B_DI) or (A_EX = C_DI)) + ) or + + -- read after write : Op1 other than STORE/NOP/JMP/JMF, op3 other than AFC/NOP/JMP/JMF, R(write) = R(read) + ( + -- check Op1 & Op2 + ((OP_DI /= x"06" and OP_DI /= x"ff" and OP_Di /= x"0F" and OP_DI /= x"10") and (Op_Mem /= x"08" and Op_Mem /= x"ff" and Op_Mem /= x"0f" and Op_Mem /= x"10")) and + + -- check Registers are the same + ((A_Mem = B_DI) or (A_Mem = C_DI)) + ) or + + -- read after write : Op1 other than STORE/NOP/JMP/JMF, op4 other than AFC/NOP/JMP/JMF, R(write) = R(read) + ( + -- check Op1 & Op2 + ((OP_DI /= x"06" and OP_DI /= x"ff" and OP_Di /= x"0F" and OP_DI /= x"10") and (Op_Re /= x"08" and Op_Re /= x"ff" and Op_Re /= x"0f" and Op_Re /= x"10")) and + + -- check Registers are the same + ((A_Re = B_DI) or (A_Re = C_DI)) + ) + or + ( + Op_EX = x"10" -- or Op_Mem = x"10" or Op_Re = x"10" + ) + else '0'; +end Behavioral; diff --git a/vhdl/CPU.vhd b/vhdl/CPU.vhd new file mode 100644 index 0000000..0cb78ca --- /dev/null +++ b/vhdl/CPU.vhd @@ -0,0 +1,364 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15.05.2023 14:29:58 +-- Design Name: +-- Module Name: CPU - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity CPU is + Port (Clk : in STD_LOGIC := '0'; + reg_addr : in STD_LOGIC_VECTOR(3 downto 0) := "0000"; + reg_val : out STD_LOGIC_VECTOR(7 downto 0)); +end CPU; + +architecture Behavioral of CPU is + + component IP is + port ( CLK : in STD_LOGIC; + RST : in STD_LOGIC; -- rst when 1 + LOAD : in STD_LOGIC; + EN : in STD_LOGIC; -- enable when 0 + Din : in STD_LOGIC_VECTOR (7 downto 0); + Dout : out STD_LOGIC_VECTOR (7 downto 0)); + end component; + + signal IP_out : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); + signal rst : STD_LOGIC := '0'; + + component InstructionMemory + Port ( Addr : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Inst_out : out STD_LOGIC_VECTOR (31 downto 0)); + end component; + + signal Li : STD_LOGIC_VECTOR (31 downto 0) := (others => '1'); + + component Stage_Li_Di + Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0); + In_B : in STD_LOGIC_VECTOR (7 downto 0); + In_C : in STD_LOGIC_VECTOR (7 downto 0); + In_Op : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Out_A : out STD_LOGIC_VECTOR (7 downto 0); + Out_B : out STD_LOGIC_VECTOR (7 downto 0); + Out_Op : out STD_LOGIC_VECTOR (7 downto 0); + Out_C : out STD_LOGIC_VECTOR (7 downto 0) + ); + end component; + + component Registers + Port ( Addr_A : in STD_LOGIC_VECTOR (3 downto 0); + Addr_B : in STD_LOGIC_VECTOR (3 downto 0); + Addr_W : in STD_LOGIC_VECTOR (3 downto 0); + Addr_C : in STD_LOGIC_VECTOR (3 downto 0); -- display on FPGA + W : in STD_LOGIC; + Data : in STD_LOGIC_VECTOR (7 downto 0); + Rst : in STD_LOGIC; + Clk : in STD_LOGIC; + QA : out STD_LOGIC_VECTOR (7 downto 0); + QB : out STD_LOGIC_VECTOR (7 downto 0); + QC : out STD_LOGIC_VECTOR (7 downto 0) + ); + end component; + + signal Di_A, Di_Op, Di_B, Di_C : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); + signal Di_RegB, Di_FinalB, Di_C2 : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); + + component Stage_Di_Ex + Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0); + In_B : in STD_LOGIC_VECTOR (7 downto 0); + In_C : in STD_LOGIC_VECTOR (7 downto 0); + In_Op : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Out_A : out STD_LOGIC_VECTOR (7 downto 0); + Out_B : out STD_LOGIC_VECTOR (7 downto 0); + Out_Op : out STD_LOGIC_VECTOR (7 downto 0); + Out_C : out STD_LOGIC_VECTOR (7 downto 0) + ); + end component; + + signal Ex_A, Ex_Op, Ex_B, Ex_C : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); + + component ALU + Port ( A : in STD_LOGIC_VECTOR (7 downto 0); + B : in STD_LOGIC_VECTOR (7 downto 0); + Ctrl_Alu : in STD_LOGIC_VECTOR (7 downto 0); + S : out STD_LOGIC_VECTOR (7 downto 0); + N : out STD_LOGIC; + O : out STD_LOGIC; + Z : out STD_LOGIC; + C : out STD_LOGIC; + JumpFlagOut : out STD_LOGIC; -- 0 false 1 true + JumpFlagIn : in STD_LOGIC + ); + end component; + + signal Ex_Ctrl_ALu, Ex_Res_Alu, Ex_FinalB : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); + signal S_NFlag, S_Oflag, S_CFlag, S_ZFlag, Jump_Flag : STD_LOGIC; + + component Stage_Ex_Mem + Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0); + In_B : in STD_LOGIC_VECTOR (7 downto 0); + In_Op : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Out_A : out STD_LOGIC_VECTOR (7 downto 0); + Out_B : out STD_LOGIC_VECTOR (7 downto 0); + Out_Op : out STD_LOGIC_VECTOR (7 downto 0) + ); + end component; + + signal Mem_A, Mem_Op, Mem_B : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); + signal Mem_RW : STD_LOGIC; + signal Mem_Addr, Mem_Data_Out, Mem_FinalB : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); + + component DataMemory + Port ( Addr : in STD_LOGIC_VECTOR (7 downto 0); + Data_in : in STD_LOGIC_VECTOR (7 downto 0); + Rw : in STD_LOGIC; + Rst : in STD_LOGIC; + Clk : in STD_LOGIC; + Data_out : out STD_LOGIC_VECTOR (7 downto 0) + ); + end component; + + component Stage_Mem_Re + Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0); + In_B : in STD_LOGIC_VECTOR (7 downto 0); + In_Op : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Out_A : out STD_LOGIC_VECTOR (7 downto 0); + Out_B : out STD_LOGIC_VECTOR (7 downto 0); + Out_Op : out STD_LOGIC_VECTOR (7 downto 0) + ); + end component; + component AleaControler is + Port ( Op_DI, Op_EX, Op_Mem, Op_Re : in STD_LOGIC_VECTOR (7 downto 0); + A_EX, A_Mem, A_Re : in STD_LOGIC_VECTOR (7 downto 0); + B_DI : in STD_LOGIC_VECTOR (7 downto 0); + C_DI : in STD_LOGIC_VECTOR (7 downto 0); + CNTRL : out STD_LOGIC + ); + end component; + + signal Re_A, Re_Op, Re_B : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); + signal Re_W : STD_LOGIC; + + -- to control jumping and where to jump + signal addr_to_jump : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); + signal jump : STD_LOGIC := '0'; + + signal nop_Cntrl : STD_LOGIC; + signal OP_LI_DI : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); + signal Di_Op_Final : STD_LOGIC_VECTOR (7 downto 0) := (others => '1'); +begin + +-- instructionPointer +inst_point : IP port map ( + CLK=> clk, + Dout=> IP_out, + Din => addr_to_jump, + RST => rst, + EN => nop_Cntrl, + LOAD => jump); + + +-- instructionMemory +MemInst : InstructionMemory PORT MAP ( + Addr => IP_out, + Clk => Clk, + Inst_out => Li); + +-- Stage_Li_Di +Stage1 : Stage_Li_Di PORT MAP ( + In_A => Li(23 downto 16), + In_B => Li(15 downto 8), + In_C => Li(7 downto 0), + In_Op => OP_LI_DI, + Clk => Clk, + Out_A => Di_A, + Out_B => Di_B, + Out_Op => Di_Op, + Out_C => Di_C); + +-- Registers +RegisterFile : Registers PORT MAP ( + Addr_A => Di_B(3 downto 0), -- because the registers are on 4 bits + Addr_B => Di_C(3 downto 0), + Addr_W => Re_A(3 downto 0), + Addr_C => reg_addr, + W => Re_W, + Data => Re_B, + Rst => Rst, + Clk => Clk, + QA => Di_RegB, + QB => Di_C2, + QC => reg_val); + +-- Stage DI/EX +Stage2 : Stage_Di_Ex PORT MAP ( + In_A => Di_A, + In_B => Di_FinalB, + In_C => Di_C2, + In_Op => Di_Op_Final, + Clk => Clk, + Out_A => Ex_A, + Out_B => Ex_B, + Out_Op => Ex_Op, + Out_C => Ex_C); + +-- ALU +Ual : ALU PORT MAP ( + A => Ex_B, + B => Ex_C, + Ctrl_Alu => Ex_Ctrl_ALu, + S => Ex_Res_Alu, + N => S_NFlag, + O => S_OFlag, + Z => S_ZFlag, + C => S_CFlag, + JumpFlagOut => Jump_Flag, + JumpFlagIn => Jump_Flag); + +-- Stage Ex/Mem +Stage3 : Stage_Ex_Mem PORT MAP ( + In_A => Ex_A, + In_B => Ex_FinalB, + In_Op => Ex_Op, + Clk => Clk, + Out_A => Mem_A, + Out_B => Mem_B, + Out_Op => Mem_Op); + +-- DataMemory +DataMem : DataMemory PORT MAP ( + Addr => Mem_Addr, + Data_in => Mem_B, + Rw => Mem_RW, + Rst => Rst, + Clk => Clk, + Data_out => Mem_Data_Out); + +-- Stage Mem/RE +Stage4 : Stage_Mem_Re PORT MAP ( + In_A => Mem_A, + In_B => Mem_FinalB, + In_Op => Mem_Op, + Clk => Clk, + Out_A => Re_A, + Out_B => Re_B, + Out_Op => Re_Op); + +-- Instruction code + -- ADD x"01" + -- MUL x"02" + -- SUB x"03" + -- DIV x"04" + -- COP x"05" + -- AFC x"06" + -- LOAD x"07" + -- STORE x"08" + -- INF x"09" + -- SUP x"0A" + -- EQ x"0B" + -- NOT x"0C" + -- AND x"0D" + -- OR x"0E" + -- JMP x"0F" + -- JMF x"10" + -- CAL x"11" + -- RET x"12" + -- PRI x"13" + -- NOP x"FF" + +-- Mux post registers +Di_FinalB <= Di_B when + Di_OP = x"06" or -- AFC + Di_OP = x"07" -- LOAD + else Di_RegB; + +-- Mux post ALU +Ex_FinalB <= Ex_B when + Ex_Op = x"06" --AFC + or Ex_Op = x"05" --COP + or Ex_Op = x"07" --LOAD + or Ex_Op = x"08" --STORE + else Ex_Res_Alu; + +-- LC pre ALU +Ex_Ctrl_ALu <= x"00" when Ex_Op = x"05" or Ex_Op = x"06" or Ex_Op = x"07" or Ex_Op = x"08" --(not using ALU) + else Ex_Op; + +-- Mux post data memory +Mem_FinalB <= Mem_B when + Mem_Op = x"06" --AFC + or Mem_Op = x"05" --COP + or Mem_Op = x"01" --ADD + or Mem_Op = x"03" -- SUB + or Mem_Op = x"02" -- MUL + or Mem_Op = x"04" -- DIV + else Mem_Data_out ; --LOAD & STORE + +-- Mux pre data memory +Mem_Addr <= Mem_B when Mem_Op = x"07" --LOAD + else Mem_A; --STORE + +-- LC pre data memory +Mem_RW <= '0' when Mem_Op = x"08" --STORE + else '1'; --STORE + +-- LC post Pip_Mem_Re +Re_W <= '0' when Re_Op = x"08" or Re_Op = x"ff" --STORE + else '1'; + +ControlUnit : AleaControler port map ( + Op_DI => Li(31 downto 24), Op_EX => Di_Op, Op_Mem => Ex_Op, Op_Re => Mem_Op, + A_EX => Di_A, A_Mem => Ex_A, A_Re => Mem_A, + B_DI => Li(15 downto 8), + C_DI => Li(7 downto 0), + CNTRL => nop_Cntrl); + + -- in case of alea : replace li(31 downto 24) by NOP + OP_LI_DI <= X"ff" when (nop_Cntrl='1' or + (Di_Op = x"10" and Jump_Flag = '1')) -- to prevent JMF + else Li(31 downto 24); + +-- jump JMP + addr_to_jump <= DI_A when (DI_OP = x"0F") -- JMP + else Di_B when (Di_Op = x"10" and Jump_Flag = '0') -- JMF + else (others => '0'); + jump <= '1' when DI_OP = x"0F" -- JMP + or (Di_Op = x"10" and Jump_Flag = '0') -- JMF + else '0'; + +-- case of JMF not triggering + Di_Op_Final <= x"ff" when (Di_Op = x"10" and Jump_Flag = '1') + else Di_Op; + + + end Behavioral; diff --git a/vhdl/IP.vhd b/vhdl/IP.vhd new file mode 100644 index 0000000..d4cade3 --- /dev/null +++ b/vhdl/IP.vhd @@ -0,0 +1,61 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 21.03.2023 15:57:28 +-- Design Name: +-- Module Name: compteur_8bits - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity IP is + Port ( CLK : in STD_LOGIC; + RST : in STD_LOGIC; -- rst when 1 + LOAD : in STD_LOGIC; + EN : in STD_LOGIC; -- enable when 0 + Din : in STD_LOGIC_VECTOR (7 downto 0); + Dout : out STD_LOGIC_VECTOR (7 downto 0)); +end IP; + +architecture Behavioral of IP is + signal aux: STD_LOGIC_VECTOR (7 downto 0) := x"00"; +begin + process + begin + wait until rising_edge(CLK); + + if (RST = '1') then + aux <= x"00"; + elsif (LOAD = '1') then + aux <= Din; + elsif (EN = '0') then + aux <= aux + x"01"; + end if; + end process; + Dout <= aux; +end Behavioral; \ No newline at end of file diff --git a/vhdl/InstructionMemory.vhd b/vhdl/InstructionMemory.vhd new file mode 100644 index 0000000..7f4f048 --- /dev/null +++ b/vhdl/InstructionMemory.vhd @@ -0,0 +1,53 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15.05.2023 13:55:29 +-- Design Name: +-- Module Name: InstructionMemory - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity InstructionMemory is + Port ( Addr : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Inst_out : out STD_LOGIC_VECTOR (31 downto 0)); +end InstructionMemory; + +architecture Behavioral of InstructionMemory is + type Mem_array is array (0 to 255) of STD_LOGIC_VECTOR (31 downto 0); +-- signal Mem : Mem_array := ((x"06000200"),(x"08020000"),(x"07000200"),(x"08000000"),(x"06000200"),(x"08020000"),(x"07000000"),(x"07010200"),(x"01000001"),(x"08030000"),(x"07000300"),(x"08010000"),others => (x"ff000000")); +-- signal Mem : Mem_array := ((x"06000200"),(x"08030000"),(x"07000300"),(x"08000000"),(x"06000600"),(x"08030000"),(x"07000000"),(x"07010300"),(x"02000001"),(x"08040000"),(x"07000400"),(x"08010000"),(x"06000200"),(x"08030000"),(x"07000100"),(x"07010300"),(x"04000001"),(x"08040000"),(x"07000400"),(x"07010000"),(x"01000001"),(x"08030000"),(x"07000300"),(x"08020000"),others => (x"ff000000")); +-- test JMP signal Mem : Mem_array := ((x"06000200"),(x"08030000"),(x"07000300"),(x"08000000"),(x"06000500"),(x"08030000"),(x"07000300"),(x"08010000"),(x"0F0D0000"),(x"06000800"),(x"08030000"),(x"07000300"),(x"08020000"),(x"06000900"),(x"08030000"),(x"07000300"),(x"08020000"),others => (x"ff000000")); +-- test JMF signal Mem : Mem_array := ((x"06000500"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000500"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"100F0000"),(x"06000800"),(x"08030000"),(x"07000300"),(x"08000000"),(x"FF000000"),others => (x"ff000000")); +-- test if else signal Mem : Mem_array := ((x"06000200"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000500"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"10021000"),(x"06000800"),(x"08030000"),(x"07000300"),(x"08000000"),(x"0F140000"),(x"06000C00"),(x"08020000"),(x"07000200"),(x"08000000"),(x"FF000000"),others => (x"ff000000")); +-- test boucle while +signal Mem : Mem_array := ((x"06000500"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000500"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"10001B00"),(x"06001400"),(x"08030000"),(x"07000000"),(x"07010300"),(x"09020001"),(x"08040200"),(x"10041B00"),(x"06000200"),(x"08010000"),(x"07000000"),(x"07010100"),(x"01000001"),(x"08030000"),(x"07000300"),(x"08000000"),(x"0F0B0000"),(x"FF000000"),others => (x"ff000000")); +-- signal Mem : Mem_array := ((x"06000200"),(x"08040000"),(x"07000400"),(x"08030000"),(x"07000000"),(x"08020000"),(x"06000200"),(x"08040000"),(x"07000200"),(x"07010400"),(x"01000001"),(x"08050000"),(x"07000500"),(x"08000000"),(x"07000300"),(x"08000000"),(x"06000500"),(x"08040000"),(x"07000400"),(x"08000000"),(x"06001300"),(x"08040000"),(x"06000200"),(x"08050000"),(x"07000400"),(x"07010500"),(x"01000001"),(x"08040000"),(x"06000500"),(x"08050000"),(x"07000500"),(x"07010000"),(x"02000001"),(x"08040000"),(x"06000800"),(x"08050000"),(x"07000400"),(x"07010500"),(x"01000001"),(x"08040000"),(x"06000200"),(x"08050000"),(x"07000400"),(x"07010500"),(x"02000001"),(x"08040000"),(x"07000400"),(x"07010400"),(x"03000001"),(x"08050000"),(x"07000500"),(x"08030000"), others => (x"ff000000")); +begin + Inst_out <= Mem(to_integer(unsigned(Addr))); +end Behavioral; diff --git a/vhdl/Memory.vhd b/vhdl/Memory.vhd new file mode 100644 index 0000000..7ae32ec --- /dev/null +++ b/vhdl/Memory.vhd @@ -0,0 +1,60 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15.05.2023 13:37:41 +-- Design Name: +-- Module Name: DataMemory - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity DataMemory is + Port ( Addr : in STD_LOGIC_VECTOR (7 downto 0); + Data_in : in STD_LOGIC_VECTOR (7 downto 0); + Rw : in STD_LOGIC; + Rst : in STD_LOGIC; + Clk : in STD_LOGIC; + Data_out : out STD_LOGIC_VECTOR (7 downto 0)); +end DataMemory; + +architecture Behavioral of DataMemory is + type Mem_array is array (0 to 255) of STD_LOGIC_VECTOR (7 downto 0); + signal Mem : Mem_array := (others => x"00"); +begin + + process + begin + wait until clk'event and clk = '1'; + if Rst = '1' then -- Reset + mem <= (others => x"00"); + else if Rw = '0' then --writing + Mem(to_integer(unsigned(Addr))) <= Data_in; + end if; + end if; + end process; + Data_out <= Mem(to_integer(unsigned(Addr))); --reading +end Behavioral; diff --git a/vhdl/Registers.vhd b/vhdl/Registers.vhd new file mode 100644 index 0000000..6b04c78 --- /dev/null +++ b/vhdl/Registers.vhd @@ -0,0 +1,79 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15.05.2023 12:56:05 +-- Design Name: +-- Module Name: registers - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity Registers is + Port ( Addr_A : in STD_LOGIC_VECTOR (3 downto 0); + Addr_B : in STD_LOGIC_VECTOR (3 downto 0); + Addr_W : in STD_LOGIC_VECTOR (3 downto 0); + Addr_C : in STD_LOGIC_VECTOR (3 downto 0); -- display on FPGA + W : in STD_LOGIC; + Data : in STD_LOGIC_VECTOR (7 downto 0); + Rst : in STD_LOGIC; + Clk : in STD_LOGIC; + QA : out STD_LOGIC_VECTOR (7 downto 0); + QB : out STD_LOGIC_VECTOR (7 downto 0); + QC : out STD_LOGIC_VECTOR (7 downto 0)); +end Registers; + +architecture Behavioral of Registers is + type Reg_array is array (0 to 15) of STD_LOGIC_VECTOR (7 downto 0); + signal Regs : Reg_array := (others => x"00"); +begin + process + begin + wait until clk'event and clk = '1'; + + if Rst = '1' then -- Reset + Regs <= (others => x"00"); + elsif W = '1' then -- Writing + Regs(to_integer(unsigned(Addr_W))) <= Data; + end if; + + end process; + + QA <= Regs(to_integer(unsigned(Addr_A))) + when W = '0' or Addr_W /= Addr_A + else Regs(to_integer(unsigned(Addr_W))) ; -- to bypass D --> Q + + QB <= Regs(to_integer(unsigned(Addr_B))) + when W = '0' or Addr_W /= Addr_B + else Regs(to_integer(unsigned(Addr_W))) ; -- to bypass D --> Q + + QC <= Regs(to_integer(unsigned(Addr_C))) + when W = '0' or Addr_W /= Addr_C + --else Regs(to_integer(unsigned(Addr_W))) + else + x"11" ; -- to bypass D --> Q + +end Behavioral; diff --git a/vhdl/Stage_Di_Ex.vhd b/vhdl/Stage_Di_Ex.vhd new file mode 100644 index 0000000..38fe1e4 --- /dev/null +++ b/vhdl/Stage_Di_Ex.vhd @@ -0,0 +1,59 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15.05.2023 14:09:59 +-- Design Name: +-- Module Name: Pipeline - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity Stage_Di_Ex is + Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0); + In_B : in STD_LOGIC_VECTOR (7 downto 0); + In_C : in STD_LOGIC_VECTOR (7 downto 0); + In_Op : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Out_A : out STD_LOGIC_VECTOR (7 downto 0); + Out_B : out STD_LOGIC_VECTOR (7 downto 0); + Out_Op : out STD_LOGIC_VECTOR (7 downto 0); + Out_C : out STD_LOGIC_VECTOR (7 downto 0) + ); +end Stage_Di_Ex; + +architecture Behavioral of Stage_Di_Ex is + +begin + process + begin + wait until clk'event and clk = '1'; + Out_A <= In_A; + Out_B <= In_B; + Out_C <= In_C; + Out_Op <= In_Op; + end process; + +end Behavioral; diff --git a/vhdl/Stage_Ex_Mem.vhd b/vhdl/Stage_Ex_Mem.vhd new file mode 100644 index 0000000..082b4e3 --- /dev/null +++ b/vhdl/Stage_Ex_Mem.vhd @@ -0,0 +1,56 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15.05.2023 14:09:59 +-- Design Name: +-- Module Name: Pipeline - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity Stage_Ex_Mem is + Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0); + In_B : in STD_LOGIC_VECTOR (7 downto 0); + In_Op : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Out_A : out STD_LOGIC_VECTOR (7 downto 0); + Out_B : out STD_LOGIC_VECTOR (7 downto 0); + Out_Op : out STD_LOGIC_VECTOR (7 downto 0) + ); +end Stage_Ex_Mem; + +architecture Behavioral of Stage_Ex_Mem is + +begin + process + begin + wait until clk'event and clk = '1'; + Out_A <= In_A; + Out_B <= In_B; + Out_Op <= In_Op; + end process; + +end Behavioral; diff --git a/vhdl/Stage_Li_Di.vhd b/vhdl/Stage_Li_Di.vhd new file mode 100644 index 0000000..88424f3 --- /dev/null +++ b/vhdl/Stage_Li_Di.vhd @@ -0,0 +1,59 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15.05.2023 14:09:59 +-- Design Name: +-- Module Name: Pipeline - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity Stage_Li_Di is + Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0); + In_B : in STD_LOGIC_VECTOR (7 downto 0); + In_C : in STD_LOGIC_VECTOR (7 downto 0); + In_Op : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Out_A : out STD_LOGIC_VECTOR (7 downto 0); + Out_B : out STD_LOGIC_VECTOR (7 downto 0); + Out_Op : out STD_LOGIC_VECTOR (7 downto 0); + Out_C : out STD_LOGIC_VECTOR (7 downto 0) + ); +end Stage_Li_Di; + +architecture Behavioral of Stage_Li_Di is + +begin + process + begin + wait until clk'event and clk = '1'; + Out_A <= In_A; + Out_B <= In_B; + Out_C <= In_C; + Out_Op <= In_Op; + end process; + +end Behavioral; diff --git a/vhdl/Stage_Mem_Re.vhd b/vhdl/Stage_Mem_Re.vhd new file mode 100644 index 0000000..4528761 --- /dev/null +++ b/vhdl/Stage_Mem_Re.vhd @@ -0,0 +1,56 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 15.05.2023 14:09:59 +-- Design Name: +-- Module Name: Pipeline - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity Stage_Mem_Re is + Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0); + In_B : in STD_LOGIC_VECTOR (7 downto 0); + In_Op : in STD_LOGIC_VECTOR (7 downto 0); + Clk : in STD_LOGIC; + Out_A : out STD_LOGIC_VECTOR (7 downto 0); + Out_B : out STD_LOGIC_VECTOR (7 downto 0); + Out_Op : out STD_LOGIC_VECTOR (7 downto 0) + ); +end Stage_Mem_Re; + +architecture Behavioral of Stage_Mem_Re is + +begin + process + begin + wait until clk'event and clk = '1'; + Out_A <= In_A; + Out_B <= In_B; + Out_Op <= In_Op; + end process; + +end Behavioral; diff --git a/vhdl/test_alu.vhd b/vhdl/test_alu.vhd new file mode 100644 index 0000000..f543e0e --- /dev/null +++ b/vhdl/test_alu.vhd @@ -0,0 +1,145 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12.05.2023 17:40:52 +-- Design Name: +-- Module Name: Test_Alu - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity Test_Alu is +-- Port ( ); +end Test_Alu; + +architecture Behavioral of Test_Alu is + + + component ALU + Port ( A : in STD_LOGIC_VECTOR (7 downto 0); + B : in STD_LOGIC_VECTOR (7 downto 0); + Ctrl_Alu : in STD_LOGIC_VECTOR (7 downto 0); -- 000 + / 001 - / 010 * / 100 Div + S : out STD_LOGIC_VECTOR (7 downto 0); + N : out STD_LOGIC; + O : out STD_LOGIC; + Z : out STD_LOGIC; + C : out STD_LOGIC); + end component; + + -- inputs + signal local_A : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); + signal local_B : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); + signal local_Ctrl_Alu : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); + + --outputs + signal local_S : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); + signal local_N : STD_LOGIC := '0'; + signal local_O : STD_LOGIC := '0'; + signal local_Z : STD_LOGIC := '0'; + signal local_C : STD_LOGIC := '0'; + + -- constant Clock_period : time := 10ns; + +begin + +-- instantiate +instance : ALU PORT MAP ( + A => local_A, + B => local_B, + Ctrl_Alu => local_Ctrl_Alu, + S => local_S, + N => local_N, + O => local_O, + Z => local_Z, + C => local_C +); + +local_Ctrl_Alu <= x"01", -- ADD + x"02" after 40 ns, -- MUL + x"03" after 60 ns, -- SUB + x"04" after 90 ns, -- DIV + x"09" after 120 ns, -- INF + x"0A" after 140 ns, -- SUP + x"0B" after 160 ns, -- EQ + x"0C" after 180 ns, -- NOT + x"0D" after 210 ns, -- XOR + x"0E" after 240 ns, -- OR + x"0F" after 270 ns; -- XOR + +local_A <= x"00", + x"00" after 10 ns, + x"0A" after 20 ns, + x"96" after 30 ns, + x"1D" after 40 ns, + x"0A" after 50 ns, + x"0B" after 60 ns, + x"0F" after 70 ns, + x"19" after 80 ns, + x"12" after 90 ns, + x"18" after 100 ns, + x"19" after 110 ns, + x"10" after 120 ns, + x"20" after 130 ns, + x"10" after 150 ns, + x"0A" after 160 ns, + x"0B" after 170 ns, + x"01" after 180 ns, + x"25" after 190 ns, + x"00" after 200 ns, + x"0A" after 210 ns, + x"00" after 230 ns, + x"0A" after 240 ns, + x"00" after 260 ns, + x"0A" after 270 ns, + x"00" after 290 ns; + +local_B <= x"00", + x"00" after 10 ns, + x"82" after 20 ns, + x"A0" after 30 ns, + x"09" after 40 ns, + x"04" after 50 ns, + x"0B" after 60 ns, + x"12" after 70 ns, + x"0B" after 80 ns, + x"00" after 90 ns, + x"06" after 100 ns, + x"07" after 110 ns, + x"20" after 120 ns, + x"10" after 130 ns, + x"20" after 150 ns, + x"0A" after 160 ns, + x"02" after 170 ns, + x"00" after 190 ns, + x"0B" after 210 ns, + x"00" after 220 ns, + x"0B" after 240 ns, + x"00" after 250 ns, + x"0B" after 270 ns, + x"00" after 280 ns; + + +end Behavioral; diff --git a/vhdl/test_cpu.vhd b/vhdl/test_cpu.vhd new file mode 100644 index 0000000..9764e95 --- /dev/null +++ b/vhdl/test_cpu.vhd @@ -0,0 +1,65 @@ + ---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 12.05.2023 17:40:52 +-- Design Name: +-- Module Name: Test_cpu - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity Test_CPU is +-- Port ( ); +end Test_CPU; + +architecture Behavioral of test_total is + + + component CPU + Port (Clk : in STD_LOGIC; + reg_addr : in STD_LOGIC_VECTOR(3 downto 0); + reg_val : out STD_LOGIC_VECTOR(7 downto 0)); + end component; + constant clock_period : time := 10 ns; + + signal clock : Std_logic := '0'; + signal a : STD_LOGIC_VECTOR(7 downto 0); + +begin + -- instantiate + Pl : CPU PORT MAP ( + Clk => clock, + reg_addr => x"0", + reg_val => a + ); + + Clock_process : process + begin + clock <= not(clock); + wait for 100ns; + end process; + +end Behavioral; diff --git a/vhdl/test_cpu.xdc b/vhdl/test_cpu.xdc new file mode 100644 index 0000000..c9f590c --- /dev/null +++ b/vhdl/test_cpu.xdc @@ -0,0 +1,26 @@ +set_property PACKAGE_PIN R2 [get_ports CLK] + set_property IOSTANDARD LVCMOS33 [get_ports CLK] +#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK] + +#set_property -dicset_property -dict {PACKAGE_PIN T18 IOSTANDARD LVCMOS33} [get_ports CLK] +#set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS33} [get_ports CLK] +#create_clock -period 10.000 -name -sysclk_pin -waveform {0.000 5.000} [get_ports CLK] + +set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets {Stage2/Jump_Flag}] + +set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVCMOS33} [get_ports {reg_addr[0]}] +set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVCMOS33} [get_ports {reg_addr[1]}] +set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {reg_addr[2]}] +set_property -dict {PACKAGE_PIN W17 IOSTANDARD LVCMOS33} [get_ports {reg_addr[3]}] + +set_property -dict {PACKAGE_PIN U16 IOSTANDARD LVCMOS33} [get_ports {reg_val[0]}] +set_property -dict {PACKAGE_PIN E19 IOSTANDARD LVCMOS33} [get_ports {reg_val[1]}] +set_property -dict {PACKAGE_PIN U19 IOSTANDARD LVCMOS33} [get_ports {reg_val[2]}] +set_property -dict {PACKAGE_PIN V19 IOSTANDARD LVCMOS33} [get_ports {reg_val[3]}] +set_property -dict {PACKAGE_PIN W18 IOSTANDARD LVCMOS33} [get_ports {reg_val[4]}] +set_property -dict {PACKAGE_PIN U15 IOSTANDARD LVCMOS33} [get_ports {reg_val[5]}] +set_property -dict {PACKAGE_PIN U14 IOSTANDARD LVCMOS33} [get_ports {reg_val[6]}] +set_property -dict {PACKAGE_PIN V14 IOSTANDARD LVCMOS33} [get_ports {reg_val[7]}] + +set_property SEVERITY {Warning} [get_drc_checks NSTD-1] +set_property SEVERITY {Warning} [get_drc_checks UCIO-1]