aboutsummaryrefslogtreecommitdiff
path: root/exp2ook.sno
blob: 7590ae421214e9aa1d659e19ee14e74645a0cc6c (plain)
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/local/bin/snobol4 -b

*	Arithmetic expression to Brainfuck/Ook! compiler
*	./exp2ook.sno [-bf] "expression"
*	Compiles "expression" and prints Ook! source to stdout
*	"-bf" prints the Brainfuck source only
*	The compiled programs calculate the result and display it (ASCII letters)

EXP2OOK	CODE('EXP2OOK')
	DEFINE('PUSH()')
	DEFINE('POP()')
	DEFINE('BINOP()NEW')
	DEFINE('COMPILE(NODE)O')

	DATA('OP(R,TYPE,L)')

	&ANCHOR = 1
	&FULLSCAN = 1

	SPACE = SPAN(" ") | ""
	PRE = SPACE ("(" *EXP SPACE ")" | SPAN("0123456789") $ *PUSH())
	POST = SPACE (ANY("+-") $ *PUSH() *EXP *BINOP() |
+		      ANY("*/") $ *PUSH() PRE *BINOP() *POST) | ""
	EXP = PRE POST

	I = HOST(3)
L.3	HOST(2, I) "-" :F(L.4)
	I = I + 1 :(L.3)
L.4	HOST(2, I) :S(L.5)
	TERMINAL = "No expression specified!" :(END)

L.5	STACK = ARRAY(10)
	SP = 0

	TRIM(HOST(2, I)) EXP RPOS(0) :S(L.6)
	TERMINAL = "Invalid expression!" :(END)

L.6	SRC = COMPILE(STACK<1>)
+	      "[>++++++++++<[->->+>>+<<<[>>+>[-]<<<-]>>[<<+>>-]"
+	      ">[-<<[<+>-]>>>+<]<<<<]>>>>>[<<<<<+>>>>>-]>[>]" DUPL("+",ORD("0"))
+	      "[<]<<<[>>>>[>]<+[<]<<<-]<[-]<]>>>>>>[>]<[.<]"

	LEQ(HOST(2, HOST(3)), "-bf") :F(L.9)
	OUTPUT = SRC :(END)

L.9	OUTPUT(.TERM, 6, "T")
	SRC ARBNO("+" *?(TERM = "Ook. Ook. ") |
+		  "-" *?(TERM = "Ook! Ook! ") |
+		  ">" *?(TERM = "Ook. Ook? ") |
+		  "<" *?(TERM = "Ook? Ook. ") |
+		  "[" *?(TERM = "Ook! Ook? ") |
+		  "]" *?(TERM = "Ook? Ook! ") |
+		  "." *?(TERM = "Ook! Ook. ") | LEN(1)) RPOS(0) :(END)

*	PROCEDURES

PUSH	PUSH = .STACK<SP = SP + 1> :(NRETURN)
POP	POP = STACK<SP>
	SP = SP - 1 :(RETURN)

BINOP	NEW = OP(POP(), POP(), POP())
	PUSH() = NEW :(RETURN)

COMPILE	LEQ(DATATYPE(NODE), .OP) :S(L.8)
	COMPILE = DUPL("+", NODE) :(RETURN)
L.8	COMPILE = COMPILE(L(NODE)) ">" COMPILE(R(NODE))
	TYPE(NODE) ANY("+-") $ O *?(COMPILE = COMPILE "[<" O ">-]<") |
+		   "*" *?(COMPILE = ">>" COMPILE "[<[<+<+>>-]<[>+<-]>>-]<[-]<<") |
+		   "/" *?(COMPILE = ">" COMPILE "<[->->+>>+<<<[>>+>[-]<<<-]>>"
+			  "[<<+>>-]>[-<<[<+>-]<<<+>>>>>]<<<<]>[-]>[-]<<<") :(RETURN)

END	EXP2OOK