-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrelative-include.fth
91 lines (73 loc) · 2.61 KB
/
relative-include.fth
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
\ Loading a file with its path relative to the file being loaded
\ The path "./" references the directory of the file being loaded.
\ The path "./../" references the parent directory of the directory of the file being loaded.
\ This is handled in `included` (as well as `include`, `required`, `require`)
\ NB: the path "../" is not treated specially; it normally refers to the parent directory
\ of the working directory of the process.
\ TODO: make path normalization by eliminating multiple "../" #maybe
wordlist dup constant module-base-uri
dup also-wordlist exch-current ( wid.compilation.previous )
: path-directory ( sd.path -- sd.directory )
\ sd.directory either ends with "/", or has zero length
over + begin 2dup u< while
char- dup c@ '/' =
until char+ then
over -
;
: s, ( sd -- ) here swap dup allot move ;
: s,copy ( sd -- sd ) here >r dup >r s, 2r> ;
0 value v_base \ the address of two slots, each of xd
: base-uri-directory ( -- sd.uri | 0 0 )
v_base dup if 2@ exit then 0
;
: base-uri ( -- sd.uri | 0 0 )
v_base dup if cell+ cell+ 2@ exit then 0
;
: push-base-uri ( sd.uri -- )
s" ./" match-head drop \ the base uri cannot be relative to the file being loaded
align v_base , here to v_base
2dup path-directory 2, 2,
;
: pop-base-uri ( -- sd.uri )
v_base if base-uri v_base cell- @ to v_base exit then
true abort" pop-base-uri: nothing to pop"
;
: drop-base-uri ( -- )
pop-base-uri 2drop
;
: concat-rev ( sd.right sd.left -- sd.result )
here >r s, s, r> here over - 0 c,
;
: expand-uri ( sd.uri -- sd.uri-expanded )
base-uri-directory concat-rev
\ 2dup ." (filename-expanded " type ." )" cr
;
: expand-uri-maybe ( sd.uri -- sd.uri-expanded )
base-uri-directory nip 0= if exit then
s" ./" match-head if expand-uri exit then
;
: execute-with-expanded-uri ( i*x sd.uri xt -- j*x )
\ xt ( i*x sd.uri-expanded -- j*x )
>r expand-uri-maybe
2dup push-base-uri
r> catch
drop-base-uri
throw
;
\ - testing
\ include ./relative-include.test.fth
( wid.compilation.previous ) exch-current ( wid.module-base-uri )
\ Export
synonym source-base-uri base-uri
synonym source-base-uri-directory base-uri-directory
: included ( any sd.uri -- any ) ['] included execute-with-expanded-uri ;
: include parse-lexeme included ;
[defined] required [if]
: required ( any sd.uri -- any ) ['] required execute-with-expanded-uri ;
: require parse-lexeme required ;
[then]
[defined] required-word [if]
: required-word ( i*x sd.word sd.filename -- j*x ) execute-with-expanded-uri ;
: require-word parse-lexeme parse-lexeme required-word ;
[then]
( wid.module-base-uri ) drop previous \ end of "module-base-uri" scope