104 lines
3.6 KiB
Plaintext
104 lines
3.6 KiB
Plaintext
Note: this is the draft grammar, with notes and some thoughts,
|
|
for the Project 2 version of Corgi
|
|
------------------
|
|
|
|
<program> -> <funcCall> | <funcCall> <funcDefs>
|
|
|
|
<funcDefs> -> <funcDef> | <funcDef> <funcDefs>
|
|
|
|
<funcDef> -> def <var> ( ) end |
|
|
def <var> ( ) <statements> end
|
|
def <var> ( <params> ) end |
|
|
def <var> ( <params> ) <statements> end
|
|
|
|
<params> -> <var> | <var> , <params>
|
|
|
|
<statements> -> <statement> |
|
|
<statement> <statements>
|
|
|
|
<funcCall> -> <var> ( ) |
|
|
<var> ( <args> )
|
|
|
|
<args> -> <expr> | <expr> , <args>
|
|
|
|
<statement> -> <string> |
|
|
<var> = <expr> |
|
|
<funcCall> |
|
|
if <expr> else end |
|
|
if <expr> else <statements> end |
|
|
if <expr> <statements> else end |
|
|
if <expr> <statements> else <statements> end |
|
|
return <expr>
|
|
|
|
<expr> -> <term> | <term> + <expr> | <term> - <expr>
|
|
<term> -> <factor> | <factor> * <term> | <factor> / <term>
|
|
|
|
<factor> -> <num> | <var> |
|
|
( <expr> ) |
|
|
- <factor> |
|
|
<funcCall>
|
|
|
|
|
|
Notes:
|
|
|
|
slightly bizarre but cool: in Corgi you can just type a string anywhere
|
|
as a statement and it gets sent to the console (still have to use
|
|
print( <expr> ) to send a number)
|
|
|
|
no boolean type---use "non-zero is true, 0 is false"
|
|
|
|
there's only the if-else---always have to use it
|
|
|
|
no loop statements---use recursion!
|
|
|
|
the built-in functions fit the grammar just like user-defined functions---
|
|
will execute differently
|
|
|
|
change the Lexer to remove /* ..... */ type of comments---no tokens
|
|
produced
|
|
|
|
NO! change Lexer to allow \n inside a string---put \\ in the Java string?
|
|
This is mildly irritating, worth adding a bif: nl()
|
|
|
|
While doing Project 2 I noticed that it's easier if we require all
|
|
functions to return (saves handling difference between hitting "end"
|
|
at the end of function that didn't do a return, and hitting "end"
|
|
elsewhere).
|
|
So, if you want to, it's okay to assume that all functions return on all
|
|
execution paths (just do like [return 0] if the function doesn't really
|
|
feel like returning a number.
|
|
|
|
Also, it's okay to require the initial funcCall to not be to a built-in
|
|
function (in my implementation, seems to be a problem (could probably be
|
|
easily fixed, but is a silly feature, anyway).
|
|
|
|
Here are the tentative official built-in functions:
|
|
|
|
lt( , ) returns 1 if first arg is less than the second
|
|
0 otherwise
|
|
le( , ) " less than or equal to "
|
|
eq( , ) " equal to
|
|
ne( , ) " not equal
|
|
|
|
or( , ) returns 1 if either arg is non-zero, 0 otherwise
|
|
and( , ) returns 1 if both args are non-zero, 0 otherwise
|
|
|
|
not( ) returns 1 if arg is zero, 0 otherwise
|
|
|
|
all the original Corgi bifs (input(), sqrt, cos, sin, atan,
|
|
pow( <expr>, <expr> )
|
|
|
|
some new ones:
|
|
|
|
print( <expr> ) just like in original Corgi, except say that if
|
|
the decimal part is 0, then don't display the .0
|
|
(this is the only bif that is called as a statement)
|
|
NOTE: print should ideally NOT display the decimal part if
|
|
it is 0 --- i.e., want 37, not 37.0
|
|
nl() prints a newline
|
|
(NOTE: unlike all other functions, funcCall to print and nl
|
|
are statements, don't return a value)
|
|
|
|
round( <expr> ) returns the value rounded to nearest integer
|
|
trunc( <expr> ) returns the value with the decimal part set to 0
|