-
-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathboot.folk
More file actions
115 lines (98 loc) · 3.8 KB
/
boot.folk
File metadata and controls
115 lines (98 loc) · 3.8 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# This program gets directly evaluated at the top level.
apply {{} {
# We setpgrp so that all subprocesses spawned by Folk, even ones
# that outlive Folk itself, can be killed later by their PGID (the
# PID in folk.pid).
catch { setpgrp }
catch {
set fp [open "folk.pid" r]
set oldPid [read $fp]; close $fp
try {
if {[string trim [exec ps -o state= -p $oldPid]] eq "Z"} {
error "Zombie Folk process exists (PID $oldPid)"
}
puts $::realStderr "boot: ($::errorCode) ERROR: Another Folk (PID $oldPid) already running."
Exit! 1
} on error e {
if {$e ne ""} {
puts stderr "boot: $e; this is OK; continuing."
}
}
}
set fp [open "folk.pid" w]
puts -nonewline $fp [pid]; close $fp
# in case we're running as root:
catch { exec chown folk folk.pid }
}}
__installLocalStdoutAndStderr "boot.folk"
Assert! when /_this/ has program code /programCode/ {
if {$_this eq "builtin-programs/collect.folk"} {
# We don't have Collect available in boot.folk yet, since it's
# implemented in userspace, so we can't do the queries. Just
# run it always.
SayWithSource $_this 1 0 {} {} \
when $programCode with environment [list [list this $_this]]
return
}
When /nobody/ wishes program $_this does not run {
When /nobody/ wishes program $_this is replaced with /...anything/ {
SayWithSource $_this 1 0 {} {} \
when $programCode with environment [list [list this $_this]]
}
When /someone/ wishes program $_this is replaced with /...replacedOpts/ {
SayWithSource $_this 1 0 {} {} \
when [dict get $replacedOpts code] with environment [list [list this $_this]]
}
}
} with environment {}
local proc LoadProgram! {programFilename} {
set fp [open $programFilename r]
set code [read $fp]
close $fp
set editedPath "$::env(HOME)/folk-data/program/[regsub {\.folk$} $programFilename {}].folk.edited"
if {[file exists $editedPath]} {
set efd [open $editedPath r]
set code [read $efd]
close $efd
}
Hold! -on boot.folk -key [list $programFilename code] \
-keep 100ms \
Claim $programFilename has program code $code
}
foreach programFilename [list {*}[glob -nocomplain builtin-programs/*.folk] \
{*}[glob -nocomplain builtin-programs/*/*.folk] \
{*}[glob -nocomplain "user-programs/[info hostname]/*.folk"] \
{*}[glob -nocomplain "$::env(HOME)/folk-data/local-program/*.folk"] \
{*}[glob -nocomplain "$::env(HOME)/folk-data/local-program/*/*.folk"]] {
if {[string match "*/_archive/*" $programFilename]} {
continue
}
LoadProgram! $programFilename
}
if {$::tcl_platform(os) eq "darwin"} {
# HACK: We must run all the GPU and window setup stuff
# synchronously in the main thread on macOS.
proc fake {s} {
set __envStack [list]
rename When When'
proc When args {
set pattern [lrange $args 0 end-1]
# Await the dependencies being available.
while {[llength [Query! {*}$pattern]] != 1} {
sleep 0.1
}
if {[lrange $pattern 0 3] eq {the GPU texture library}} {
# HACK: We want Whens inside this block to be normal
# Whens and run off-thread/async.
rename When {}
rename When' When
}
tailcall ForEach! {*}$args
}
source $s
rename When {}
rename When' When
}
fake "builtin-programs/gpu/gpu.folk"
fake "builtin-programs/gpu/draw.folk"
}