-
Notifications
You must be signed in to change notification settings - Fork 2
/
llox.lua
91 lines (77 loc) · 2 KB
/
llox.lua
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
package.path = package.path .. ';src/?.lua'
local scan = require 'scan.scan'
local parse = require 'parse.parse'
local Interpreter = require 'interpret.Interpreter'
local Resolver = require 'resolve.Resolver'
local interpreter
local resolver
local had_error, had_runtime_error
local function report(line, where, message)
io.stderr:write('[line ' .. line .. '] Error' .. where .. ': ' .. message .. '\n')
had_error = true
end
local function general_error(line, message)
report(line, '', message)
end
local function parse_error(token, message)
if token.type == 'EOF' then
report(token.line, ' at end', message)
else
report(token.line, " at '" .. token.lexeme .. "'", message)
end
end
local function resolution_error(err)
report(err.token.line, " at '" .. err.token.lexeme .. "'", err.message)
end
local function runtime_error(err)
print(err)
io.stderr:write(err.message .. '\n[line ' .. err.token.line .. ']\n')
had_runtime_error = true
end
local function run(source)
local tokens = scan(source, general_error)
if had_error then return end
local statements = parse(tokens, parse_error)
if had_error then return end
resolver.resolve(statements)
if had_error then return end
interpreter.interpret(statements)
if had_runtime_error then return end
end
local function read_file(path)
local f = io.open(path, 'r')
assert(f, 'file ' .. path .. ' does not exist or cannot be opened')
local contents = f:read('*all')
f:close()
return contents
end
local function run_file(path)
run(read_file(path))
if had_error then
os.exit(65)
end
if had_runtime_error then
os.exit(70)
end
end
local function run_prompt()
while true do
io.write('> ')
local input = io.read()
if not input then
print()
return
end
run(input)
had_error = false
end
end
interpreter = Interpreter(runtime_error)
resolver = Resolver(interpreter, resolution_error)
if #arg > 1 then
print('Usage: lox [script]')
elseif #arg == 1 then
run_file(arg[1])
else
run_prompt()
end