2021-09-24 20:13:52 +02:00
|
|
|
// Copyright (c) 2021 Lars Pontoppidan. All rights reserved.
|
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
module ast
|
|
|
|
|
|
|
|
import toml.token
|
2021-11-18 18:46:19 +01:00
|
|
|
import strconv
|
2021-09-24 20:13:52 +02:00
|
|
|
|
|
|
|
// Key is a sumtype representing all types of keys that
|
|
|
|
// can be found in a TOML document.
|
|
|
|
pub type Key = Bare | Bool | Null | Number | Quoted
|
|
|
|
|
|
|
|
pub fn (k Key) str() string {
|
|
|
|
return k.text
|
|
|
|
}
|
|
|
|
|
2021-09-25 19:31:02 +02:00
|
|
|
// Value is a sumtype representing all possible value types
|
2021-09-24 20:13:52 +02:00
|
|
|
// found in a TOML document.
|
2021-09-25 19:31:02 +02:00
|
|
|
pub type Value = Bool
|
|
|
|
| Date
|
|
|
|
| DateTime
|
|
|
|
| Null
|
|
|
|
| Number
|
|
|
|
| Quoted
|
|
|
|
| Time
|
|
|
|
| []Value
|
|
|
|
| map[string]Value
|
2021-09-24 20:13:52 +02:00
|
|
|
|
2021-11-18 12:27:59 +01:00
|
|
|
// str outputs the value in JSON-like format for eased
|
|
|
|
// debugging
|
|
|
|
pub fn (v Value) str() string {
|
2021-09-24 20:13:52 +02:00
|
|
|
match v {
|
|
|
|
Quoted, Date, DateTime, Time {
|
2021-11-18 12:27:59 +01:00
|
|
|
return '"$v.text"'
|
2021-09-24 20:13:52 +02:00
|
|
|
}
|
|
|
|
Bool, Null, Number {
|
2021-11-18 12:27:59 +01:00
|
|
|
return v.text
|
2021-09-24 20:13:52 +02:00
|
|
|
}
|
2021-09-25 19:31:02 +02:00
|
|
|
map[string]Value {
|
2021-09-24 20:13:52 +02:00
|
|
|
mut str := '{'
|
|
|
|
for key, val in v {
|
2021-11-18 12:27:59 +01:00
|
|
|
str += ' "$key": $val,'
|
2021-09-24 20:13:52 +02:00
|
|
|
}
|
|
|
|
str = str.trim_right(',')
|
|
|
|
str += ' }'
|
|
|
|
return str
|
|
|
|
}
|
2021-09-25 19:31:02 +02:00
|
|
|
[]Value {
|
2021-09-24 20:13:52 +02:00
|
|
|
mut str := '['
|
|
|
|
for val in v {
|
2021-11-18 12:27:59 +01:00
|
|
|
str += ' $val,'
|
2021-09-24 20:13:52 +02:00
|
|
|
}
|
|
|
|
str = str.trim_right(',')
|
|
|
|
str += ' ]'
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// DateTimeType is a sumtype representing all possible date types
|
|
|
|
// found in a TOML document.
|
|
|
|
pub type DateTimeType = Date | DateTime | Time
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `DateTimeType` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (dtt DateTimeType) str() string {
|
|
|
|
return dtt.text
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// Comment is the data representation of a TOML comment (`# This is a comment`).
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct Comment {
|
|
|
|
pub:
|
|
|
|
text string
|
|
|
|
pos token.Position
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `Comment` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (c Comment) str() string {
|
|
|
|
mut s := typeof(c).name + '{\n'
|
|
|
|
s += ' text: \'$c.text\'\n'
|
|
|
|
s += ' pos: $c.pos\n'
|
|
|
|
s += '}'
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
// Null is used in sumtype checks as a "default" value when nothing else is possible.
|
|
|
|
pub struct Null {
|
|
|
|
pub:
|
|
|
|
text string
|
|
|
|
pos token.Position
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `Null` type
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (n Null) str() string {
|
|
|
|
return n.text
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// Quoted is the data representation of a TOML quoted type (`"quoted-key" = "I'm a quoted value"`).
|
|
|
|
// Quoted types can appear both as keys and values in TOML documents.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct Quoted {
|
2021-11-20 18:48:44 +01:00
|
|
|
pub mut:
|
|
|
|
text string
|
2021-09-24 20:13:52 +02:00
|
|
|
pub:
|
2021-09-28 16:40:03 +02:00
|
|
|
pos token.Position
|
|
|
|
is_multiline bool
|
|
|
|
quote byte
|
2021-09-24 20:13:52 +02:00
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `Quoted` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (q Quoted) str() string {
|
|
|
|
mut str := typeof(q).name + '{\n'
|
|
|
|
str += ' text: \'$q.text\'\n'
|
|
|
|
str += ' pos: $q.pos\n'
|
2021-09-28 16:40:03 +02:00
|
|
|
str += ' is_multiline: $q.is_multiline\n'
|
|
|
|
str += ' quote: \'$q.quote\'\n'
|
2021-09-24 20:13:52 +02:00
|
|
|
str += '}'
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// Bare is the data representation of a TOML bare type (`bare_key = ...`).
|
|
|
|
// Bare types can appear only as keys in TOML documents. Otherwise they take the
|
|
|
|
// form of Bool or Numbers.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct Bare {
|
|
|
|
pub:
|
|
|
|
text string
|
|
|
|
pos token.Position
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `Bare` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (b Bare) str() string {
|
|
|
|
mut str := typeof(b).name + '{\n'
|
|
|
|
str += ' text: \'$b.text\'\n'
|
|
|
|
str += ' pos: $b.pos\n'
|
|
|
|
str += '}'
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// Bool is the data representation of a TOML boolean type (`... = true`).
|
|
|
|
// Bool types can appear only as values in TOML documents. Keys named `true` or `false`
|
|
|
|
// are considered as Bare types.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct Bool {
|
|
|
|
pub:
|
|
|
|
text string
|
|
|
|
pos token.Position
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `Bool` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (b Bool) str() string {
|
|
|
|
mut str := typeof(b).name + '{\n'
|
|
|
|
str += ' text: \'$b.text\'\n'
|
|
|
|
str += ' pos: $b.pos\n'
|
|
|
|
str += '}'
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// Number is the data representation of a TOML number type (`25 = 5e2`).
|
|
|
|
// Number types can appear both as keys and values in TOML documents.
|
|
|
|
// Number can be integers, floats, infinite, NaN - they can have exponents (`5e2`) and be sign prefixed (`+2`).
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct Number {
|
|
|
|
pub:
|
2021-11-23 15:23:16 +01:00
|
|
|
pos token.Position
|
|
|
|
pub mut:
|
2021-09-24 20:13:52 +02:00
|
|
|
text string
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `Number` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (n Number) str() string {
|
|
|
|
mut str := typeof(n).name + '{\n'
|
|
|
|
str += ' text: \'$n.text\'\n'
|
|
|
|
str += ' pos: $n.pos\n'
|
|
|
|
str += '}'
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2021-11-18 18:46:19 +01:00
|
|
|
// i64 returns the `n Number` as an `i64` value.
|
|
|
|
pub fn (n Number) i64() i64 {
|
|
|
|
if n.text.starts_with('0x') {
|
|
|
|
hex := n.text.all_after('0x').to_upper().replace('_', '')
|
|
|
|
return strconv.parse_int(hex, 16, 64) or { i64(0) }
|
|
|
|
} else if n.text.starts_with('0o') {
|
|
|
|
oct := n.text.all_after('0o').replace('_', '')
|
|
|
|
return strconv.parse_int(oct, 8, 64) or { i64(0) }
|
|
|
|
} else if n.text.starts_with('0b') {
|
|
|
|
bin := n.text.all_after('0b').replace('_', '')
|
|
|
|
return strconv.parse_int(bin, 2, 64) or { i64(0) }
|
|
|
|
}
|
2021-11-23 12:23:16 +01:00
|
|
|
return strconv.parse_int(n.text, 0, 64) or { i64(0) }
|
2021-11-18 18:46:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// f64 returns the `n Number` as an `f64` value.
|
|
|
|
pub fn (n Number) f64() f64 {
|
|
|
|
return n.text.replace('_', '').f64()
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// Date is the data representation of a TOML date type (`YYYY-MM-DD`).
|
|
|
|
// Date types can appear both as keys and values in TOML documents.
|
|
|
|
// Keys named like dates e.g. `1980-12-29` are considered Bare key types.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct Date {
|
|
|
|
pub:
|
|
|
|
text string
|
|
|
|
pos token.Position
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `Date` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (d Date) str() string {
|
|
|
|
mut str := typeof(d).name + '{\n'
|
|
|
|
str += ' text: \'$d.text\'\n'
|
|
|
|
str += ' pos: $d.pos\n'
|
|
|
|
str += '}'
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// Time is the data representation of a TOML time type (`HH:MM:SS.milli`).
|
|
|
|
// Time types can appear only as values in TOML documents.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct Time {
|
|
|
|
pub:
|
|
|
|
text string
|
|
|
|
offset int
|
|
|
|
pos token.Position
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `Time` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (t Time) str() string {
|
|
|
|
mut str := typeof(t).name + '{\n'
|
|
|
|
str += ' text: \'$t.text\'\n'
|
|
|
|
str += ' offset: \'$t.offset\'\n'
|
|
|
|
str += ' pos: $t.pos\n'
|
|
|
|
str += '}'
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// DateTime is the data representation of a TOML date-time type (`YYYY-MM-DDTHH:MM:SS.milli`).
|
|
|
|
// DateTime types can appear only as values in TOML documents.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct DateTime {
|
2021-11-24 13:49:23 +01:00
|
|
|
pub mut:
|
2021-09-24 20:13:52 +02:00
|
|
|
text string
|
2021-11-24 13:49:23 +01:00
|
|
|
pub:
|
2021-09-24 20:13:52 +02:00
|
|
|
pos token.Position
|
|
|
|
date Date
|
|
|
|
time Time
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `DateTime` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (dt DateTime) str() string {
|
|
|
|
mut str := typeof(dt).name + '{\n'
|
|
|
|
str += ' text: \'$dt.text\'\n'
|
|
|
|
str += ' date: \'$dt.date\'\n'
|
|
|
|
str += ' time: \'$dt.time\'\n'
|
|
|
|
str += ' pos: $dt.pos\n'
|
|
|
|
str += '}'
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// EOF is the data representation of the end of the TOML document.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub struct EOF {
|
|
|
|
pub:
|
|
|
|
pos token.Position
|
|
|
|
}
|
|
|
|
|
2021-09-26 06:34:47 +02:00
|
|
|
// str returns the `string` representation of the `EOF` type.
|
2021-09-24 20:13:52 +02:00
|
|
|
pub fn (e EOF) str() string {
|
|
|
|
mut str := typeof(e).name + '{\n'
|
|
|
|
str += ' pos: $e.pos\n'
|
|
|
|
str += '}'
|
|
|
|
return str
|
|
|
|
}
|