separate number into float and integer
This commit is contained in:
parent
10f55313b0
commit
daab50d54c
22 changed files with 848 additions and 428 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -203,10 +204,11 @@ func (p *Parser) advance() {
|
|||
|
||||
if p.pos < Pos(len(p.tokens)) {
|
||||
p.curr = &p.tokens[p.pos]
|
||||
p.pos++
|
||||
} else {
|
||||
panic("no more tokens")
|
||||
p.curr = nil
|
||||
}
|
||||
|
||||
p.pos++
|
||||
}
|
||||
|
||||
func (p *Parser) error(error string, causer *Token) error {
|
||||
|
|
@ -229,15 +231,29 @@ func (p *Parser) factor() (Node, error) {
|
|||
p.prev.Start + p.prev.Length,
|
||||
}, nil
|
||||
|
||||
case TokenNumber:
|
||||
case TokenInteger:
|
||||
p.advance()
|
||||
num, err := strconv.ParseFloat((*p.prev).Lexeme, NumberSize)
|
||||
|
||||
num, success := new(big.Int).SetString(p.prev.Lexeme, 10)
|
||||
if !success {
|
||||
return nil, p.error(fmt.Sprintf("cannot parse integer base 10: %s", p.prev.Lexeme), p.prev)
|
||||
}
|
||||
|
||||
return &IntegerNode{
|
||||
num,
|
||||
p.prev.Start,
|
||||
p.prev.Start + p.prev.Length,
|
||||
}, nil
|
||||
|
||||
case TokenFloat:
|
||||
p.advance()
|
||||
num, err := strconv.ParseFloat((*p.prev).Lexeme, FloatSize)
|
||||
|
||||
if err != nil {
|
||||
return nil, p.error(fmt.Sprintf("Error parsing number: %v", err), p.prev)
|
||||
}
|
||||
|
||||
return &NumberNode{
|
||||
return &FloatNode{
|
||||
num,
|
||||
p.prev.Start,
|
||||
p.prev.Start + p.prev.Length,
|
||||
|
|
@ -246,13 +262,13 @@ func (p *Parser) factor() (Node, error) {
|
|||
case TokenHexadecimal:
|
||||
p.advance()
|
||||
start := (*p.prev).Start
|
||||
num, err := strconv.ParseUint((*p.prev).Lexeme[2:], 16, NumberSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
num, ok := new(big.Int).SetString(p.prev.Lexeme[2:], 16)
|
||||
if !ok {
|
||||
return nil, p.error(fmt.Sprintf("cannot parse hexadecimal: %v", p.prev.Lexeme), p.prev)
|
||||
}
|
||||
|
||||
return &NumberNode{
|
||||
float64(num),
|
||||
return &IntegerNode{
|
||||
num,
|
||||
start,
|
||||
p.prev.Start + p.prev.Length,
|
||||
}, nil
|
||||
|
|
@ -280,6 +296,8 @@ func (p *Parser) factor() (Node, error) {
|
|||
p.advance()
|
||||
start := p.prev.Start
|
||||
|
||||
// TODO: find better solution; current one is messy
|
||||
// Maybe perform better analysis to determine the kind of the list...
|
||||
if p.accept(TokenCloseBracket) {
|
||||
s, err := p.parseSignature()
|
||||
if err != nil {
|
||||
|
|
@ -390,7 +408,7 @@ func (p *Parser) factor() (Node, error) {
|
|||
}
|
||||
|
||||
var sig TypeSignature = &NilSignature{}
|
||||
if p.curr.Type != TokenOpenBrace {
|
||||
if p.accept(TokenArrow) {
|
||||
sig, err = p.parseSignature()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -744,7 +762,7 @@ func (p *Parser) statement() (Node, error) {
|
|||
}
|
||||
|
||||
var yield TypeSignature = &NilSignature{}
|
||||
if p.curr.Type != TokenOpenBrace {
|
||||
if p.accept(TokenArrow) {
|
||||
yield, err = p.parseSignature()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -983,8 +1001,10 @@ func (p *Parser) parseSignature() (TypeSignature, error) {
|
|||
switch name {
|
||||
case "string":
|
||||
s = &StringSignature{}
|
||||
case "number":
|
||||
s = &NumberSignature{}
|
||||
case "int":
|
||||
s = &IntegerSignature{}
|
||||
case "float":
|
||||
s = &FloatSignature{}
|
||||
case "boolean":
|
||||
s = &BooleanSignature{}
|
||||
case "list":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue