separate number into float and integer

This commit is contained in:
Neemek 2026-07-07 23:24:44 +02:00
parent 10f55313b0
commit daab50d54c
Signed by: neemek
GPG key ID: 84FFE4D7D40AB25E
22 changed files with 848 additions and 428 deletions

View file

@ -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":