numbers are back, yay

master
Jordan Orelli 10 years ago
parent 9c317ec358
commit 7cd65a4025

@ -5,6 +5,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"strconv"
"strings" "strings"
) )
@ -16,6 +17,7 @@ const (
n_comment n_comment
n_assignment n_assignment
n_string n_string
n_number
) )
var indent = " " var indent = " "
@ -216,5 +218,78 @@ func (s *stringNode) eval(ctx map[string]interface{}) (interface{}, error) {
return string(*s), nil return string(*s), nil
} }
type numberType int
const (
num_int numberType = iota
num_float
num_complex
)
type numberNode struct {
t numberType
c complex128
i int
f float64
}
func (n *numberNode) Type() nodeType {
return n_number
}
func (n *numberNode) parse(p *parser) error {
t := p.next()
if t.t != t_real_number {
return fmt.Errorf("unexpected %s token while parsing number", t.t)
}
if p.peek().t == t_imaginary_number {
n.t = num_complex
s := t.s + p.next().s
if _, err := fmt.Sscan(s, &n.c); err != nil {
return fmt.Errorf("ungood imaginary number format %s: %s", s, err)
}
return nil
}
i, err := strconv.ParseInt(t.s, 0, 64)
if err == nil {
n.t = num_int
n.i = int(i)
return nil
}
f, err := strconv.ParseFloat(t.s, 64)
if err == nil {
n.t = num_float
n.f = f
return nil
}
return fmt.Errorf("this token broke the number parser: %s", t)
}
func (n *numberNode) pretty(w io.Writer, prefix string) error {
v, err := n.eval(nil)
if err != nil {
return err
}
fmt.Fprintf(w, "%s%v\n", prefix, v)
return nil
}
func (n *numberNode) eval(ctx map[string]interface{}) (interface{}, error) {
switch n.t {
case num_int:
return n.i, nil
case num_float:
return n.f, nil
case num_complex:
return n.c, nil
default:
panic("whoerps")
}
}
type list []interface{} type list []interface{}
type object map[string]interface{} type object map[string]interface{}

@ -3,7 +3,6 @@ package main
import ( import (
"fmt" "fmt"
"io" "io"
"strconv"
) )
const () const ()
@ -87,9 +86,12 @@ func (p *parser) parseValue() (node, error) {
return nil, err return nil, err
} }
return n, nil return n, nil
// case t_real_number, t_imaginary_number: case t_real_number:
// p.unread(t) n := new(numberNode)
// return p.number() if err := n.parse(p); err != nil {
return nil, err
}
return n, nil
// case t_list_start: // case t_list_start:
// return p.parseList(make(list, 0, 4)) // return p.parseList(make(list, 0, 4))
// case t_object_start: // case t_object_start:
@ -149,31 +151,3 @@ func (p *parser) parseObject(obj object) (object, error) {
return p.parseObject(obj) return p.parseObject(obj)
} }
} }
func (p *parser) number() (interface{}, error) {
t := p.next()
if t.t != t_real_number {
return nil, fmt.Errorf("unexpected %s token while parsing number", t.t)
}
if p.peek().t == t_imaginary_number {
var c complex128
s := t.s + p.next().s
if _, err := fmt.Sscan(s, &c); err != nil {
return nil, fmt.Errorf("ungood imaginary number format %s: %s", s, err)
}
return c, nil
}
i, err := strconv.ParseInt(t.s, 0, 64)
if err == nil {
return int(i), nil
}
f, err := strconv.ParseFloat(t.s, 64)
if err == nil {
return f, nil
}
return nil, fmt.Errorf("this token broke the number parser: %s", t)
}

@ -0,0 +1 @@
# comments should be removed from the parse tree

@ -0,0 +1,2 @@
root{
}

@ -0,0 +1,17 @@
a_string: "a string value"
an_int: 1
another_int: +9
moar_int: -12
a_float: 1.0
another_float: -.9
extra_floaty: +1.2
complex1: 1+1i
complex2: 1+0i
complex3: 1.3+4.7i
complex4: -4.2+8.9i
complex5: +4.2-8.9i

@ -0,0 +1,50 @@
root{
assign{
name: a_string
value: a string value
}
assign{
name: an_int
value: 1
}
assign{
name: another_int
value: 9
}
assign{
name: moar_int
value: -12
}
assign{
name: a_float
value: 1
}
assign{
name: another_float
value: -0.9
}
assign{
name: extra_floaty
value: 1.2
}
assign{
name: complex1
value: (1+1i)
}
assign{
name: complex2
value: (1+0i)
}
assign{
name: complex3
value: (1.3+4.7i)
}
assign{
name: complex4
value: (-4.2+8.9i)
}
assign{
name: complex5
value: (4.2-8.9i)
}
}
Loading…
Cancel
Save