123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- package dirty
- import (
- "math"
- "strconv"
- "strings"
- )
- type Int int
- func (Int) isElement() {}
- func (Int) getType() ElementType {
- return ElemInt
- }
- func (i Int) String() string {
- return strconv.FormatInt(int64(i), 10)
- }
- type Float float64
- func (Float) isElement() {}
- func (Float) getType() ElementType {
- return ElemFloat
- }
- func (i Float) String() string {
- return strconv.FormatFloat(float64(i), 'f', -1, 64)
- }
- func convertDozenal(d string) string {
- result := ""
- for _, c := range d {
- if c == '↊' {
- result += "a"
- } else if c == '↋' {
- result += "b"
- } else if c == '·' {
- result += "."
- } else {
- result += string(c)
- }
- }
- return result
- }
- func parseNumber(t token) (token, error) {
- l := len(t.t)
- if (in('.', []rune(t.t)) && t.t[l-1] != '.') || (in('·', []rune(t.t)) && t.t[l-1] != '·') {
- return parseFloat(t)
- } else if in('e', []rune(t.t)) && t.t[0] != '0' {
- return parseEngFloat(t)
- } else {
- return parseInt(t)
- }
- }
- func parseFloat(t token) (token, error) {
- t.ttype = FLOAT
- if in('·', []rune(t.t)) {
- number := strings.SplitN(convertDozenal(t.t), ".", 2)
- whole, err := strconv.ParseInt(number[0], 12, 64)
- if err != nil {
- return token{}, err
- }
- fraction, err := strconv.ParseUint(number[1], 12, 64)
- if err != nil {
- return token{}, err
- }
- t.t = ""
- w := float64(whole)
- if fraction != 0 {
- var sign float64
- if w < 0 {
- sign = -1.0
- } else {
- sign = 1.0
- }
- l := math.Floor(math.Log10((float64(fraction))/math.Log10(12)) + 1)
- w += (float64(fraction) / math.Pow(12, l)) * sign
- }
- t.f = &w
- return t, nil
- } else {
- f, err := strconv.ParseFloat(t.t, 64)
- t.t = ""
- t.f = &f
- return t, err
- }
- }
- func parseEngFloat(t token) (token, error) {
- t.ttype = FLOAT
- number := strings.SplitN(t.t, "e", 2)
- a, err := strconv.ParseFloat(number[0], 64)
- if err != nil {
- return token{}, err
- }
- b, err := strconv.ParseInt(number[1], 10, 64)
- if err != nil {
- return token{}, err
- }
- num := a * math.Pow10(int(b))
- t.t = ""
- t.f = &num
- return t, nil
- }
- func parseComma(num string, z int) (string, error) {
- num2 := ""
- prevIsComma := false
- lastComma := -1
- zeroes := ""
- for i := 0; i < z; i++ {
- zeroes += "0"
- }
- for i, d := range num {
- if d == ',' {
- if prevIsComma {
- num2 += zeroes
- } else if !((i-lastComma) == z+1 || lastComma == -1) {
- return "", NewCommaError(num)
- }
- lastComma = i
- } else {
- num2 += string(d)
- }
- prevIsComma = d == ','
- }
- return num2, nil
- }
- func parseInt(t token) (token, error) {
- num2 := t.t
- base := 10
- if t.t[0] == '0' && t.t[1] == 'b' {
- num := t.t[2:]
- if num[0] == ',' {
- num = "1" + num
- }
- var err error = nil
- num2, err = parseComma(num, 8)
- if err != nil {
- return token{}, err
- }
- num2 = "0b" + num2
- base = 0
- }
- if t.t[0] == '0' && t.t[1] == 'o' {
- num2 = t.t
- base = 0
- }
- if t.t[0] == '0' && t.t[1] == 'x' {
- num2 = t.t
- base = 0
- }
- if in('·', []rune(t.t)) {
- num, err := parseComma(t.t, 3) // 4?
- if err != nil {
- return token{}, err
- }
- num2 = convertDozenal(num)
- num2 = num2[:len(num2)-1]
- base = 12
- }
- if in('.', []rune(t.t)) {
- num2 = t.t[:len(t.t)-1]
- var err error = nil
- parseComma(num2, 3)
- if err != nil {
- return token{}, err
- }
- base = 10
- }
- result, err := strconv.ParseInt(num2, base, 64)
- t.i = &result
- return t, err
- }
|