The first thing the interpreter will do is compile the core definitions in
the library file. Once this is complete you can start entering forth commands:
- : star 42 emit ;
- ok
- star
- * ok
-
-Notice that unlike other forths, forth.jl echos a newline after reading each
-line of standard input. This is an unfortunate side-effect of the way that
-I've implemented EXPECT. Hopefully I'll be able to fix this in future.
+ : star 42 emit ; ok
+ star * ok
There's an example Mandelbrot Set drawing program included in the examples
directory. To run it, you'll have to locate this directory on your system (its
**
ok
+To exit, enter ^D on a blank line or use the `bye` word.
+
## License
This package is free software and is distributed under version 3.0 of the GNU
currentSource() = sources[length(sources)]
EOF = defPrimWord("\x04", () -> begin
- close(pop!(sources))
- if !isempty(sources)
+ if currentSource() != STDIN
+ close(pop!(sources))
return NEXT
else
return 0
end
end
-KEY = defPrimWord("KEY", () -> begin
+function getKey()
raw_mode!(true)
- pushPS(Int(readbytes(STDIN, 1)[1]))
+ byte = readbytes(STDIN, 1)[1]
raw_mode!(false)
+
+ if byte == 0x0d
+ return 0x0a
+ elseif byte == 127
+ return 0x08
+ else
+ return byte
+ end
+end
+
+KEY = defPrimWord("KEY", () -> begin
+ pushPS(Int(getKey()))
return NEXT
end)
+function getLineFromSTDIN()
+ line = ""
+ while true
+ key = Char(getKey())
+
+ if key == '\n'
+ print(" ")
+ return ASCIIString(line)
+
+ elseif key == '\x04'
+ if isempty(line)
+ return string("\x04")
+ end
+
+ elseif key == '\b'
+ if !isempty(line)
+ line = line[1:length(line)-1]
+ print("\b \b")
+ end
+
+ elseif key == '\e'
+ # Strip ANSI escape sequence
+ nextKey = Char(getKey())
+ if nextKey == '['
+ while true
+ nextKey = Char(getKey())
+ if nextKey >= '@' || nextKey <= '~'
+ break
+ end
+ end
+ end
+
+ else
+ print(key)
+ line = string(line, key)
+ end
+ end
+end
+
SPAN, SPAN_CFA = defNewVar("SPAN", 0)
EXPECT = defPrimWord("EXPECT", () -> begin
maxLen = popPS()
addr = popPS()
- if !eof(currentSource())
- line = chomp(readline(currentSource()))
- mem[SPAN] = min(length(line), maxLen)
- putString(line[1:mem[SPAN]], addr)
+ if currentSource() == STDIN
+ line = getLineFromSTDIN()
else
- mem[SPAN] = 1
- mem[addr] = 4 # eof
+ if !eof(currentSource())
+ line = chomp(readline(currentSource()))
+ else
+ line = "\x04" # eof
+ end
end
+ mem[SPAN] = min(length(line), maxLen)
+ putString(line[1:mem[SPAN]], addr)
+
return NEXT
end)
end)
BYE = defPrimWord("BYE", () -> begin
- println("Bye!")
+ println("\nBye!")
return 0
end)
count = popPS()
addr = popPS()
+ println()
dump(addr, count=count)
return NEXT