summaryrefslogtreecommitdiffstats
path: root/l6/calc.py
diff options
context:
space:
mode:
Diffstat (limited to 'l6/calc.py')
-rw-r--r--l6/calc.py187
1 files changed, 187 insertions, 0 deletions
diff --git a/l6/calc.py b/l6/calc.py
new file mode 100644
index 0000000..ea4d2b3
--- /dev/null
+++ b/l6/calc.py
@@ -0,0 +1,187 @@
+# ----------------------------------------------------------------------------
+# Grammar for the Calc language
+# ----------------------------------------------------------------------------
+
+"""
+
+PROGRAM ::= '[' 'calc' ',' STATEMENTS ']'
+
+STATEMENTS ::= STATEMENT
+ | STATEMENT ',' STATEMENTS
+
+STATEMENT ::= ASSIGNMENT
+ | REPETITION
+ | SELECTION
+ | INPUT
+ | OUTPUT
+
+ASSIGNMENT ::= '[' 'set' ',' VARIABLE ',' EXPRESSION ']'
+
+REPETITION ::= '[' 'while' ',' CONDITION ',' STATEMENTS ']'
+
+SELECTION ::= '[' 'if' ',' CONDITION ',' STATEMENT ']'
+ | '[' 'if' ',' CONDITION ',' STATEMENT ',' STATEMENT ']'
+
+INPUT ::= '[' 'read' ',' VARIABLE ']'
+
+OUTPUT ::= '[' 'print' ',' VARIABLE ']'
+
+EXPRESSION ::= CONSTANT
+ | VARIABLE
+ | BINARYEXPR
+
+BINARYEXPR ::= '[' EXPRESSION ',' BINARYOPER ',' EXPRESSION ']'
+
+CONDITION ::= '[' EXPRESSION ',' CONDOPER ',' EXPRESSION ']'
+
+BINARYOPER ::= '+' | '-' | '*' | '/'
+
+CONDOPER ::= '<' | '>' | '='
+
+VARIABEL ::= a Python string
+
+KONSTANT ::= a Python number
+
+"""
+
+# ----------------------------------------------------------------------------
+# Primitive functions for the Calc language constructs
+# ----------------------------------------------------------------------------
+
+# ----- PROGRAM -----
+
+def isprogram(p):
+ return isinstance(p, list) and len(p) > 1 and p[0] == 'calc'
+
+def program_statements(p):
+ return p[1:]
+
+# ----- STATEMENTS -----
+
+def isstatements(p):
+ isstmnt = lambda s: isassignment(s) or isrepetition(s) or isselection(s) \
+ or isoutput(s) or isinput(s)
+ return isinstance(p, list) and p and all(map(isstmnt, p))
+
+def first_statement(p):
+ return p[0]
+
+def rest_statements(p):
+ return p[1:]
+
+def empty_statements(p):
+ return not p
+
+# ----- STATEMENT -----
+
+# No functions for statements in general. Instead, see the differenct
+# types of statements: assignments, repetitions, selections, input
+# and output.
+
+# ----- ASSIGNMENT -----
+
+def isassignment(p):
+ return isinstance(p, list) and len(p) == 3 and p[0] == 'set'
+
+def assignment_variable(p):
+ return p[1]
+
+def assignment_expression(p):
+ return p[2]
+
+# ----- REPETITION -----
+
+def isrepetition(p):
+ return isinstance(p, list) and len(p) > 2 and p[0] == 'while'
+
+def repetition_condition(p):
+ return p[1]
+
+def repetition_statements(p):
+ return p[2:]
+
+# ----- SELECTION -----
+
+def isselection(p):
+ return isinstance(p, list) and (3 <= len(p) <= 4) and p[0] == 'if'
+
+def selection_condition(p):
+ return p[1]
+
+def selection_true(p):
+ return p[2]
+
+def hasfalse(p):
+ return len(p) == 4
+
+def selection_false(p):
+ return p[3]
+
+# ----- INPUT -----
+
+def isinput(p):
+ return isinstance(p, list) and len(p) == 2 and p[0] == 'read'
+
+def input_variable(p):
+ return p[1]
+
+# ----- OUTPUT -----
+
+def isoutput(p):
+ return isinstance(p, list) and len(p) == 2 and p[0] == 'print'
+
+def output_variable(p):
+ return p[1]
+
+# ----- EXPRESSION -----
+
+# No functions for expressions in general. Instead, see the differenct
+# types of expressions: constants, variables and binary expressions.
+
+# ----- BINARYEXPR -----
+
+def isbinary(p):
+ return isinstance(p, list) and len(p) == 3 and isbinaryoper(p[1])
+
+def binary_operator(p):
+ return p[1]
+
+def binary_left(p):
+ return p[0]
+
+def binary_right(p):
+ return p[2]
+
+# ----- CONDITION -----
+
+def iscondition(p):
+ return isinstance(p, list) and len(p) == 3 and iscondoper(p[1])
+
+def condition_operator(p):
+ return p[1]
+
+def condition_left(p):
+ return p[0]
+
+def condition_right(p):
+ return p[2]
+
+# ----- BINARYOPER -----
+
+def isbinaryoper(p):
+ return p in ['+', '-', '*', '/']
+
+# ----- CONDOPER -----
+
+def iscondoper(p):
+ return p in ['<', '>', '=']
+
+# ----- VARIABLE -----
+
+def isvariable(p):
+ return isinstance(p, str) and p != ""
+
+# ----- CONSTANT -----
+
+def isconstant(p):
+ return isinstance(p, int) or isinstance(p, float)