diff options
-rw-r--r-- | README.md | 44 | ||||
-rw-r--r-- | res/syntax.ebnf | 47 | ||||
-rw-r--r-- | src/driver.c | 2 | ||||
-rw-r--r-- | src/repl.c | 14 |
4 files changed, 98 insertions, 9 deletions
@@ -13,4 +13,46 @@ A small interpreter of the IMP programming language. - [flex](https://github.com/westes/flex) - [bison](https://www.gnu.org/software/bison) -- [readline](https://tiswww.case.edu/php/chet/readline/rltop.html)
\ No newline at end of file +- [readline](https://tiswww.case.edu/php/chet/readline/rltop.html) + +## IMP + +[Syntax](/res/syntax.ebnf) + +**Statement <stm>** +Variable assignment: +- `<var> := <aexp>` any variable not assigned, has the value 0. + +Local variable: +- `var <var> := <aexp> in <stm> end` + +Control flow: +- `if <bexp> then <stm> else <stm> end` +- `while <bexp> do <stm> end` +- `(<stm>; <stm>)` sequential composition, the first statement runs before the second +- `skip`, nop + +**Expression** +Arithmetic Expression <aexp>: +- `<num>` +- `<var>` +- `(<aexp> + <aexp>) +- `(<aexp> - <aexp>) +- `(<aexp> + <aexp>) + +Boolean Expression <bexp>: +- `not <bexp> +- `(<bexp> or <bexp>) +- `(<bexp> and <bexp>) +- `<aexp> = <aexp>` +- `<aexp> # <aexp>` not equals +- `<aexp> < <aexp>` +- `<aexp> <= <aexp>` +- `<aexp> > <aexp>` +- `<aexp> >= <aexp>` + +**Variable <var>** +- `[a-zA-Z][A-Za-z0-9]*` + +**Numeral <num>** +- `[0-9]+` diff --git a/res/syntax.ebnf b/res/syntax.ebnf new file mode 100644 index 0000000..85990c5 --- /dev/null +++ b/res/syntax.ebnf @@ -0,0 +1,47 @@ +letter_uppercase = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" + | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" + ; + +letter_lowercase = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" + | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" + ; + +letter = letter_uppercase | letter_lowercase + ; + +digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + ; + +identifier = letter , { letter | digit } + ; + +numeral = digit | ( numeral , digit ) + ; + +variable = identifier + ; + +arithmetic_operation = "+" | "-" | "*" + ; + +arithmetic_expression = ( "(" , arithmetic_expression , arithmetic_operation , arithmetic_expression , ")" ) + | variable | numeral ; + +boolean_operation = "or" | "not" + ; + +relational_operation = "=" | "#" | "<" | "<=" | ">" | ">=" + ; + +boolean_expression = ( "(" , boolean_expression , boolean_operation , boolean_expression , ")" ) + | ( "not" , boolean_expression ) + | ( arithmetic_expression , relational_operation , arithmetic_expression ) + ; + +statement = "skip" + | ( variable , ":=" , arithmetic_expression ) + | ( "(" , statement , ";" , "statement" , ")" ) + | ( "if" , boolean_expression , "then" , statement , "else" , statement , "end" ) + | ( "while" , boolean_expression , "do" , statement , "end" ) + | ( "var" , variable , ":=", arithmetic_expression , "in" , statement , "end" ) + ;
\ No newline at end of file diff --git a/src/driver.c b/src/driver.c index 60d3ce2..fc2a3ae 100644 --- a/src/driver.c +++ b/src/driver.c @@ -25,7 +25,7 @@ int main(int argc, char **argv) { fprintf(stderr, "Usage: %s [-i program.imp]\n" " -i <program.imp> interpret program and exit\n" - " (no args) start REPL\n", + " (no args) start REPL\n", argv[0]); return (opt == 'h') ? EXIT_SUCCESS : EXIT_FAILURE; } @@ -7,14 +7,14 @@ #include <string.h> static void print_help(void) { - puts( - "IMP REPL (type IMP statements or commands starting with '%')\n" + printf( + "IMP REPL (type IMP statements or commands starting with '%%')\n" "Commands:\n" - " %quit exit\n" - " %run <path/to/file.imp> interpret program\n" - " %set <var> <val> set variable\n" - " %print [<var>] print variable, or all variables\n" - " %help show this message\n"); + " %%quit exit\n" + " %%run <path/to/file.imp> interpret program\n" + " %%set <var> <val> set variable\n" + " %%print [<var>] print variable, or all variables\n" + " %%help show this message\n"); } static void repl_exec_command(hashmap_t context, const char *command) { |