-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathTokenInput.zu
124 lines (107 loc) · 2.95 KB
/
TokenInput.zu
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
#
# The Zimbu compiler written in Zimbu
#
# TokenInput class.
#
# Copyright 2009 Bram Moolenaar All Rights Reserved.
# Licensed under the Apache License, Version 2.0. See the LICENSE file or
# obtain a copy at: http://www.apache.org/licenses/LICENSE-2.0
#
IMPORT "Input.zu"
IMPORT "Token.zu"
IMPORT "Tokenizer.zu"
#= Wraps around an Input. Input does the character level stuff, TokenInput
#= the token level stuff.
CLASS TokenInput @items=public # TODO: restrict visibility
Input $input
list<Token> $tokenStack # pushed back tokens
# Keep track of which Token.Type.id keywords have been used in this file.
# This is for loading a built-in library only when it is used.
set<string> $usedIdKeywords
# Create a TokenInput for |input|.
NEW(Input input)
$input = input
$tokenStack = NEW()
$usedIdKeywords = NEW()
}
# Low level input function.
# Gets one character at a time, removing CR characters.
# Uses pushed character if there is one.
# Returns IO.eof when there is nothing more to read.
FUNC $get() int
RETURN $input.get()
}
# Push |c| back, a following get() will use it.
PROC $push(int c)
$input.push(c)
}
# Get the next character and push it back.
FUNC $peek() int
int c = $get()
$push(c)
RETURN c
}
# Read a word, consisting only of ASCII alpha characters and '_'.
# Does not skip over white space or punctuation.
# Returns an empty string when the first character is not alpha.
FUNC $getWord() string
IO.StringWriter sw = NEW()
WHILE TRUE
int c = $get()
IF !c.isAlpha() && c != '_'
$push(c)
BREAK
}
sw.write(c.asString())
}
RETURN sw.ToString()
}
# Skip over white space. Return TRUE if at least one space was encountered.
FUNC $skipWhite() bool
int c = $get()
IF c != ' '
$push(c)
RETURN FALSE
}
WHILE c == ' '
c = $get()
}
$push(c)
RETURN TRUE
}
# When there is a previously pushed back token, return it.
# Otherwise read a token from the file and return it.
FUNC $getToken() Token
IF $tokenStack.Size() > 0
RETURN $tokenStack.remove()
}
RETURN Tokenizer.get(THIS)
}
# Push |token| back, a following getToken() will use it.
PROC $pushToken(Token token)
$tokenStack.add(token)
}
# Return the next token to be read without actually reading it.
FUNC $peekToken() Token
IF $tokenStack.Size() > 0
RETURN $tokenStack[$tokenStack.Size() - 1]
}
Token token = Tokenizer.get(THIS)
$tokenStack.add(token)
RETURN token
}
# Push tokens on the stack back to the input.
# Used when switching from reading tokens to reading input directly.
PROC $emptyStack()
WHILE $tokenStack.Size() > 0
Token t = $tokenStack.remove()
FOR i IN t.value.Size() - 1 TO 0 STEP -1
$push(t.value[i])
}
}
}
# Log an error at the current input position.
PROC $error(string msg)
LOG.error(msg, $input.pos)
}
}