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
|
lfs = require 'lfs'
import parse, globals, Scope, Error, Registry from require 'core'
slurp = (file) ->
file = io.open file, 'r'
with file\read '*all'
file\close!
spit = (file, str) ->
file = io.open file, 'w'
file\write str
file\close!
class Copilot
new: (@file) =>
@registry = Registry!
@last_modification = 0
mode = lfs.attributes @file, 'mode'
if mode != 'file'
error "not a file: #{@file}"
tick: =>
@poll!
if @root
@registry\begin_tick!
ok, error = Error.try "updating", ->
@root\tick_io!
@root\tick!
if not ok
print error
@registry\end_tick!
eval: =>
@registry\begin_eval!
ok, ast = Error.try "parsing '#{@file}'", parse, slurp @file
if not ok
print ast
@registry\rollback_eval!
return
scope = Scope globals
ok, root = Error.try "evaluating '#{@file}'", ast\eval, scope, @registry
if not ok
print root
@registry\rollback_eval!
return
@registry\end_eval!
@root = root
spit @file, ast\stringify!
poll: =>
{ :mode, :modification } = (lfs.attributes @file) or {}
if mode != 'file'
return
if @last_modification < modification
L\log "#{@file} changed at #{modification}"
@eval!
@last_modification = os.time!
{
:Copilot
}
|