aboutsummaryrefslogtreecommitdiff
path: root/exp2ook.sc
blob: 41b040f3b7a151b5f67d7c2392f61a0e812a6e4a (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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Snocone version (obscure C-like SNOBOL preprocessor)

stack = array(10); sp = 0

procedure push()
{
	nreturn .stack[sp = sp + 1]
}

procedure pop()
{
	pop = stack[sp]
	sp = sp - 1
}

procedure printstack() i
{
	for (i = sp, i > 0, i = i - 1)
		output = stack[i]
}

struct op {r, type, l}

procedure binop() new
{
	new = op(pop(), pop(), pop())
	push() = new
}

space = span(" ") | ""
pre = space && "(" && *exp && space && ")" | space && span("0123456789") $ *push()
post = space && any("+-") $ *push() && *exp && *binop() |
       space && any("*/") $ *push() && pre && *binop() && *post | ""
exp = pre && post

&anchor = 1

for (i = host(3), host(2, i) ? "-", i = i + 1) {}
if (~host(2, i)) {
	terminal = "No expression specified!"
	go to end
}

if (~(trim(host(2, i)) ? exp && rpos(0))) {
	terminal = "Invalid expression!"
	go to end
}

procedure eval(node) left, right
{
	if (datatype(node) :!=: .op)
		return convert(node, "integer")

	left = eval(l(node))
	right = eval(r(node))

	type(node) ? "+" && *?(eval = left + right) |
		     "-" && *?(eval = left - right) |
		     "*" && *?(eval = left * right) |
		     "/" && *?(eval = left / right)
}

#output = eval(stack[1])

procedure compile(node) o
{
	if (datatype(node) :!=: .op)
		return dupl("+", node)

	compile = compile(l(node)) && ">" && compile(r(node))

	type(node) ? any("+-") $ o && *?(compile = compile && "[<" && o && ">-]<") | # a0 += a1 | a0 -= a1
		     "*" && *?(compile = ">>" && compile && "[<[<+<+>>-]<[>+<-]>>-]<[-]<<") | # a0 *= a1
		     "/" && *?(compile = ">" && compile && "<[->->+>>+<<<[>>+>[-]<<<-]>>[<<+>>-]>[-<<[<+>-]<<<+>>>>>]<<<<]>[-]>[-]<<<") # a0 /= a1
}

src = compile(stack[1]) &&
     "[>++++++++++<[->->+>>+<<<[>>+>[-]<<<-]>>[<<+>>-]>[-<<[<+>-]>>>+<]<<<<]>>>>>[<<<<<+>>>>>-]>[>]" &&
     dupl("+", 48) && "[<]<<<[>>>>[>]<+[<]<<<-]<[-]<]>>>>>>[>]<[.<]"

if (host(2, host(3)) :==: "-bf") {
	output = src
} else {
	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)
}