Skip to content

Commit

Permalink
support hex number literal
Browse files Browse the repository at this point in the history
  • Loading branch information
douyixuan committed Sep 11, 2024
1 parent 9248a12 commit bbc945a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 25 deletions.
22 changes: 22 additions & 0 deletions compiler/lexer/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (
IDENTIFIER lexType = iota
KEYWORD
NUMBER
HEX
STRING
BYTE
OPERATOR
Expand Down Expand Up @@ -238,9 +239,30 @@ func Lex(inputFullSource string) []Item {
// NUMBER
// 0-9
lexNumber := func() bool {
isHex := false
if i + 1 < len(input) {
if input[i] == '0' && input[i+1] == 'x' {
isHex = true
i += 2
}
}
if i >= len(input) {
return false
}
if isHex {
if (input[i] >= '0' && input[i] <= '9') || (input[i] >= 'a' && input[i] <= 'f') || (input[i] >= 'A' && input[i] <= 'F') {
val := ""
for (input[i] >= '0' && input[i] <= '9') || (input[i] >= 'a' && input[i] <= 'f') || (input[i] >= 'A' && input[i] <= 'F') {
val += string(input[i])
i++
if i >= len(input) {
break
}
}
res = append(res, Item{Type: HEX, Val: val, Line: line})
return true
}
}
if input[i] >= '0' && input[i] <= '9' {
val := ""
for i < len(input) && input[i] >= '0' && input[i] <= '9' {
Expand Down
71 changes: 46 additions & 25 deletions compiler/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,33 @@ func (p *parser) parseOne(withAheadParse bool) (res Node) {
return p.parseOneWithOptions(withAheadParse, withAheadParse, withAheadParse)
}

func (p *parser) parseNumberSuffix() (ty TypeNode) {
next := p.lookAhead(1)
if next.Type == lexer.IDENTIFIER {
switch next.Val {
case "u8":
ty = &SingleTypeNode{SourceName: "uint8", TypeName: "uint8"}
p.i++
case "u16":
ty = &SingleTypeNode{SourceName: "uint16", TypeName: "uint16"}
p.i++
case "u32":
ty = &SingleTypeNode{SourceName: "uint32", TypeName: "uint32"}
p.i++
case "u64":
ty = &SingleTypeNode{SourceName: "uint64", TypeName: "uint64"}
p.i++
case "u128":
ty = &SingleTypeNode{SourceName: "uint128", TypeName: "uint128"}
p.i++
case "u256":
ty = &SingleTypeNode{SourceName: "uint256", TypeName: "uint256"}
p.i++
}
}
return
}

func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentifierAhead bool) (res Node) {
current := p.input[p.i]

Expand Down Expand Up @@ -91,41 +118,35 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif
}
return


// HEX always returns a ConstantNode
// Convert string hex representation to int64
case lexer.HEX:
val, err := strconv.ParseInt(current.Val, 16, 64)
if err != nil {
panic(err)
}
res = &ConstantNode{
Type: NUMBER,
TargetType: p.parseNumberSuffix(),
Value: val,
}
if withAheadParse {
res = p.aheadParse(res)
}
return

// NUMBER always returns a ConstantNode
// Convert string representation to int64
case lexer.NUMBER:
val, err := strconv.ParseInt(current.Val, 10, 64)
if err != nil {
panic(err)
}
next := p.lookAhead(1)
var ty TypeNode
if next.Type == lexer.IDENTIFIER {
switch next.Val {
case "u8":
ty = &SingleTypeNode{SourceName: "uint8", TypeName: "uint8"}
p.i++
case "u16":
ty = &SingleTypeNode{SourceName: "uint16", TypeName: "uint16"}
p.i++
case "u32":
ty = &SingleTypeNode{SourceName: "uint32", TypeName: "uint32"}
p.i++
case "u64":
ty = &SingleTypeNode{SourceName: "uint64", TypeName: "uint64"}
p.i++
case "u128":
ty = &SingleTypeNode{SourceName: "uint128", TypeName: "uint128"}
p.i++
case "u256":
ty = &SingleTypeNode{SourceName: "uint256", TypeName: "uint256"}
p.i++
}
}

res = &ConstantNode{
Type: NUMBER,
TargetType: ty,
TargetType: p.parseNumberSuffix(),
Value: val,
}
if withAheadParse {
Expand Down
5 changes: 5 additions & 0 deletions tests/examples/number-literal.cell
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,10 @@ func main() {
if f != uint256(600) {
return 6
}

aa := 0xffffu32
if aa != uint32(65535) {
return 11
}
return 0
}

0 comments on commit bbc945a

Please sign in to comment.