-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmoonforth.moon
78 lines (67 loc) · 1.6 KB
/
moonforth.moon
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
import MiniForth from require "miniforth"
import stack from require "stack"
class MoonForth extends MiniForth
new: (subj = "") =>
super subj
eval = (str, chunkname) ->
load = if loadstring
loadstring
else
load
-- set up the environment
with _G
.self = @
.dictionary = @dictionary
.DS = @DS
.eval = eval
load str, chunkname
@DS = stack!
@add_words
"%L": -> assert(eval(@parse_rest_of_line!, "%L"))({})
"\n": ->
"": -> @mode = "stop"
"[L": -> assert(eval(@parse_by_pattern "^(.-)%sL]()", "[L"))()
"?DUP": -> @DS\push @DS\peek! if @DS\peek! ~= 0
"2DUP": ->
s1, s2 = @DS\pop 2
@DS\push s2, s1, s2, s1
"DUP": -> @DS\push @DS\peek! if @DS\peek!
"2DROP": -> @DS\pop 2
"DROP": -> @DS\pop!
"ROT": ->
f, s, t = @DS\pop 3
@DS\push f, t, s
"SWAP": ->
f, s = @DS\pop! 2
@DS\push f, s
"+": -> @DS\push @DS\pop! + @DS\pop!
"-": ->
@dictionary.SWAP!
@DS\push @DS\pop! - @DS\pop!
"*": -> @DS\push @DS\pop! * @DS\pop!
"/": ->
@dictionary.SWAP!
@DS\push @DS\pop! / @DS\pop!
"*/": ->
@dictionary["/"]!
@dictionary["*"]!
"MOD": ->
@dictionary.SWAP!
@DS\push math.fmod @DS\pop!, @DS\pop!
"NEGATE": -> @DS\push -1 * @DS\pop!
"1+": ->
@DS\push 1
@dictionary["+"]!
"1-": ->
@DS\push 1
@dictionary["-"]!
".": -> io.write " " .. @DS\pop!
"ABS": -> @DS\push math.abs @DS\pop!
"MAX": -> @DS\push math.max @DS\pop 2
"MIN": -> @DS\push math.min @DS\pop 2
interpret_number: =>
number = tonumber @word
if number then
@DS\push number
true
{ :MoonForth }