-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.nim
51 lines (38 loc) · 1.16 KB
/
main.nim
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
import sequtils
import tables
import os
import util
import parse
import instrs
proc has_only_nans(stack: seq[uint64]): bool =
stack.all(proc (item: uint64): bool = cast[float64](item).`$` == "nan")
proc execute*(stack: seq[uint64]): void =
# make `var` copy of supplied stack
var stack = stack[0 ..< stack.len]
var instr_ptr = 0'u64
while true:
# Enforce stack being only nans
if not stack.has_only_nans:
abort "NeN"
# Error if instruction pointer is out of bounds
if instr_ptr < 0 or instr_ptr.int >= stack.len:
abort "NiB"
let instr_code = stack[instr_ptr]
# Error if instruction is unknown
if instr_code notin instr_impls_by_code:
abort "NaI"
# Break if instruction is to terminate
if instr_code == symbol_to_code("stop"):
break
# Execute instruction
let instr: Instr = instr_impls_by_code[instr_code]
instr(stack, instr_ptr)
proc execute*(source: string): void =
let instrs = parse(source)
execute instrs
when isMainModule:
if paramCount() != 1:
abort "Expected exactly one command-line argument"
let filename = paramStr(1)
let source = filename.readFile
execute source