-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTuringCompleteParser.caf
48 lines (38 loc) · 1.96 KB
/
TuringCompleteParser.caf
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class TcParser extends &CaffeineEight.Parser
getStore: -> @store ?= []
getContext: -> @context ?= {}
operators = {}
getOperator = (op) -> operators[op] ?= eval "(a, b) => a #{op} b"
############################################
# SEQUENCING
@rule root: [] "expression nextExpr* _? ';'?" evaluate: ->
reduce last, e in @nextExprs inject @expression.evaluate() do e.expression.evaluate()
@rule nextExpr: [] "_? ';' _? expression"
############################################
# ARITHMETIC
@rule expression: [] "operand _? op:/==|!=|<=|>=|[-+*\\/<>]/ _? operand" evaluate: ->
getOperator(@op.text) (array op in @operands with op.evaluate())...
@rule expression: [] "operand" evaluate: -> @operand.evaluate()
@rule operand: [] "'(' _? root _? ')'" evaluate: -> @root.evaluate()
@rule operand: [] /-?[0-9]+/ evaluate: -> eval @text
@rule _: [] /\s+/
############################################
# MEMORY
@rule expression: [] "'[' _? expression _? ']' _? '=' _? value:expression" evaluate: ->
@parser.getStore()[@expression.evaluate()] = @value.evaluate()
@rule expression: [] "'[' _? expression _? ']'" evaluate: ->
@parser.getStore()[@expression.evaluate()]
############################################
# LOOPING AND CONDITIONALS
@rule operand: [] "'while' _ test:expression _ 'do' _ body:expression" evaluate: ->
while @test.evaluate() do @body.evaluate()
@rule operand: [] "'if' _ test:expression _ 'then' _ then:expression _ else?" evaluate: ->
if @test.evaluate() then @then.evaluate() else @else?.expression.evaluate()
@rule else: [] "'else' _ expression"
############################################
# VARIABLES
@rule operand: [] "identifier _? '=' _? expression" evaluate: ->
@parser.getContext()[@identifier.text] = @expression.evaluate()
@rule operand: [] "identifier" evaluate: -> @parser.getContext()[@identifier.text]
@rule identifier: [] /\w+/
.repl()