-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoken.os
148 lines (122 loc) · 4.79 KB
/
token.os
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
!
! BRACY/TOKEN. Read tokens from a Bracy source file.
!
! Copyright © 2012 James B. Moen.
!
! This program is free software: you can redistribute it and/or modify it
! under the terms of the GNU General Public License as published by the Free
! Software Foundation, either version 3 of the License, or (at your option)
! any later version.
!
! This program is distributed in the hope that it will be useful, but WITHOUT
! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
! FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
! more details.
!
! You should have received a copy of the GNU General Public License along with
! this program. If not, see <http://www.gnu.org/licenses/>.
!
(prog
! Constants. They represent source tokens.
makeToken :− enum(high(int0))
blankToken :− makeToken() ! Separate words and scopes.
closeToken :− makeToken() ! End a scope.
endFileToken :− makeToken() ! End of source file.
endLineToken :− makeToken() ! End of source line.
endParaToken :− makeToken() ! End of source paragraph.
openToken :− makeToken() ! Begin a scope.
wordToken :− makeToken() ! A series of non-whitespace chars.
! Variables.
var int token :− blankToken ! Current token.
var ref object tokenObject :− nil ! TOKEN's corresponding object.
! NEXT TOKEN. Scan the next token using subtokens read from SOURCE.
nextToken :−
(proc () void:
(with
! NEXT BLANK. Scan a BLANK TOKEN.
nextBlank :−
(form () void:
token := blankToken
tokenObject := nil
nextSubtoken())
! NEXT CLOSE. Scan a CLOSE TOKEN. This is always a non-style scope because the
! subtoken scanner keeps track of style scopes (see BRACY/SUBTOKEN).
nextClose :−
(form () void:
token := closeToken
tokenObject := nil
nextSubtoken())
! NEXT END FILE. Scan an END FILE TOKEN. Don't read the next subtoken, because
! there isn't one.
nextEndFile :−
(form () void:
token := endFileToken
tokenObject := nil)
! NEXT END LINE. Skip BLANK SUBTOKENs and END LINE SUBTOKENs, counting the END
! LINE SUBTOKENs. Two or more END LINE SUBTOKENs gives an END PARAGRAPH TOKEN;
! just one gives us an END LINE TOKEN.
nextEndLine :−
(form () void:
(with var int count :− 0
do (while
(if subtoken = blankSubtoken
then nextSubtoken()
true
else if subtoken = endLineSubtoken
then count += 1
nextSubtoken()
true
else false))
(if count > 1
then token := endParaToken
tokenObject := endParaAtom
else token := endLineToken
tokenObject := endLineAtom)))
! NEXT OPEN. Scan an OPEN TOKEN. This always corresponds to a non-style scope,
! since the subtoken scanner keeps track of style scopes (see BRACY/SUBTOKEN).
nextOpen :−
(form () void:
token := openToken
tokenObject := subtokenObject
nextSubtoken())
! NEXT WORD. Scan a WORD TOKEN: a series of one or more GLYPH SUBTOKENs.
nextWord :−
(form () void:
empty(wordChars)
empty(wordStyles)
(while subtoken = glyphSubtoken
do appendCharAndStyle(wordChars, wordStyles)
nextSubtoken())
token := wordToken
tokenObject := makeWord(wordChars, wordStyles))
! NEXT UNKNOWN. Scan an unknown token. This should never happen.
nextUnknown :−
(form () void:
syntaxError(unknownTokenErr)
token := blankToken
tokenObject := nil
nextSubtoken())
! This is NEXT TOKEN's body. Look at CH to decide what token we have, and then
! dispatch to code that scans it. Repeat until we get a token other than BLANK
! TOKEN.
do (while
(case subtoken
of blankSubtoken: nextBlank()
closeSubtoken: nextClose()
endFileSubtoken: nextEndFile()
endLineSubtoken: nextEndLine()
glyphSubtoken: nextWord()
openSubtoken: nextOpen()
none: nextUnknown())
token = blankToken)))
! APPEND CHAR AND STYLE. Add GLYPH TOKEN's char and style to the buffers CHARS
! and STYLES, respectively. Only lower case chars get CAPITAL CODE.
appendCharAndStyle :−
(form (var char0Buffer chars, var setBuffer styles) void:
append(chars, subtokenChar)
(if capitalCode ∊ subtokenStyle
then (if isLower(subtokenChar)
then append(styles, subtokenStyle)
else append(styles, subtokenStyle − capitalCode))
else append(styles, subtokenStyle)))
)