aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavian Kaufmann <flavian@flaviankaufmann.ch>2025-05-21 07:45:30 +0200
committerFlavian Kaufmann <flavian@flaviankaufmann.ch>2025-05-21 07:45:30 +0200
commit5a90102b20d18966b69496d85361d14c085479db (patch)
treec44f7c89f84841131f248fbaf2f85bca13517c2f
parent40cccdb7cc472ee6300c25e1774a8489e9107f6a (diff)
downloadimp-5a90102b20d18966b69496d85361d14c085479db.tar.gz
imp-5a90102b20d18966b69496d85361d14c085479db.zip
syntax doc
-rw-r--r--README.md44
-rw-r--r--res/syntax.ebnf47
-rw-r--r--src/driver.c2
-rw-r--r--src/repl.c14
4 files changed, 98 insertions, 9 deletions
diff --git a/README.md b/README.md
index dc39ac2..a86f2df 100644
--- a/README.md
+++ b/README.md
@@ -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;
}
diff --git a/src/repl.c b/src/repl.c
index 9c61b98..5ea9792 100644
--- a/src/repl.c
+++ b/src/repl.c
@@ -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) {