Skip to content

Commit bbc945a

Browse files
committed
support hex number literal
1 parent 9248a12 commit bbc945a

File tree

3 files changed

+73
-25
lines changed

3 files changed

+73
-25
lines changed

compiler/lexer/lexer.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const (
1111
IDENTIFIER lexType = iota
1212
KEYWORD
1313
NUMBER
14+
HEX
1415
STRING
1516
BYTE
1617
OPERATOR
@@ -238,9 +239,30 @@ func Lex(inputFullSource string) []Item {
238239
// NUMBER
239240
// 0-9
240241
lexNumber := func() bool {
242+
isHex := false
243+
if i + 1 < len(input) {
244+
if input[i] == '0' && input[i+1] == 'x' {
245+
isHex = true
246+
i += 2
247+
}
248+
}
241249
if i >= len(input) {
242250
return false
243251
}
252+
if isHex {
253+
if (input[i] >= '0' && input[i] <= '9') || (input[i] >= 'a' && input[i] <= 'f') || (input[i] >= 'A' && input[i] <= 'F') {
254+
val := ""
255+
for (input[i] >= '0' && input[i] <= '9') || (input[i] >= 'a' && input[i] <= 'f') || (input[i] >= 'A' && input[i] <= 'F') {
256+
val += string(input[i])
257+
i++
258+
if i >= len(input) {
259+
break
260+
}
261+
}
262+
res = append(res, Item{Type: HEX, Val: val, Line: line})
263+
return true
264+
}
265+
}
244266
if input[i] >= '0' && input[i] <= '9' {
245267
val := ""
246268
for i < len(input) && input[i] >= '0' && input[i] <= '9' {

compiler/parser/parser.go

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,33 @@ func (p *parser) parseOne(withAheadParse bool) (res Node) {
6363
return p.parseOneWithOptions(withAheadParse, withAheadParse, withAheadParse)
6464
}
6565

66+
func (p *parser) parseNumberSuffix() (ty TypeNode) {
67+
next := p.lookAhead(1)
68+
if next.Type == lexer.IDENTIFIER {
69+
switch next.Val {
70+
case "u8":
71+
ty = &SingleTypeNode{SourceName: "uint8", TypeName: "uint8"}
72+
p.i++
73+
case "u16":
74+
ty = &SingleTypeNode{SourceName: "uint16", TypeName: "uint16"}
75+
p.i++
76+
case "u32":
77+
ty = &SingleTypeNode{SourceName: "uint32", TypeName: "uint32"}
78+
p.i++
79+
case "u64":
80+
ty = &SingleTypeNode{SourceName: "uint64", TypeName: "uint64"}
81+
p.i++
82+
case "u128":
83+
ty = &SingleTypeNode{SourceName: "uint128", TypeName: "uint128"}
84+
p.i++
85+
case "u256":
86+
ty = &SingleTypeNode{SourceName: "uint256", TypeName: "uint256"}
87+
p.i++
88+
}
89+
}
90+
return
91+
}
92+
6693
func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentifierAhead bool) (res Node) {
6794
current := p.input[p.i]
6895

@@ -91,41 +118,35 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif
91118
}
92119
return
93120

121+
122+
// HEX always returns a ConstantNode
123+
// Convert string hex representation to int64
124+
case lexer.HEX:
125+
val, err := strconv.ParseInt(current.Val, 16, 64)
126+
if err != nil {
127+
panic(err)
128+
}
129+
res = &ConstantNode{
130+
Type: NUMBER,
131+
TargetType: p.parseNumberSuffix(),
132+
Value: val,
133+
}
134+
if withAheadParse {
135+
res = p.aheadParse(res)
136+
}
137+
return
138+
94139
// NUMBER always returns a ConstantNode
95140
// Convert string representation to int64
96141
case lexer.NUMBER:
97142
val, err := strconv.ParseInt(current.Val, 10, 64)
98143
if err != nil {
99144
panic(err)
100145
}
101-
next := p.lookAhead(1)
102-
var ty TypeNode
103-
if next.Type == lexer.IDENTIFIER {
104-
switch next.Val {
105-
case "u8":
106-
ty = &SingleTypeNode{SourceName: "uint8", TypeName: "uint8"}
107-
p.i++
108-
case "u16":
109-
ty = &SingleTypeNode{SourceName: "uint16", TypeName: "uint16"}
110-
p.i++
111-
case "u32":
112-
ty = &SingleTypeNode{SourceName: "uint32", TypeName: "uint32"}
113-
p.i++
114-
case "u64":
115-
ty = &SingleTypeNode{SourceName: "uint64", TypeName: "uint64"}
116-
p.i++
117-
case "u128":
118-
ty = &SingleTypeNode{SourceName: "uint128", TypeName: "uint128"}
119-
p.i++
120-
case "u256":
121-
ty = &SingleTypeNode{SourceName: "uint256", TypeName: "uint256"}
122-
p.i++
123-
}
124-
}
125146

126147
res = &ConstantNode{
127148
Type: NUMBER,
128-
TargetType: ty,
149+
TargetType: p.parseNumberSuffix(),
129150
Value: val,
130151
}
131152
if withAheadParse {

tests/examples/number-literal.cell

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,10 @@ func main() {
2727
if f != uint256(600) {
2828
return 6
2929
}
30+
31+
aa := 0xffffu32
32+
if aa != uint32(65535) {
33+
return 11
34+
}
3035
return 0
3136
}

0 commit comments

Comments
 (0)