all repos

clerk @ 1efa5a1

missing tooling for ledger/hledger

clerk/journal/ast/ast.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
journal: tags support, 2 months ago
1
package ast
2
3
import (
4
	"strings"
5
6
	"olexsmir.xyz/clerk/journal/token"
7
)
8
9
type Journal struct {
10
	Entries []Entry
11
	Errors  []*ParseError
12
}
13
14
type Entry interface {
15
	entryNode()
16
}
17
18
type ParseError struct {
19
	Span    token.Span
20
	Message string
21
}
22
23
type FileError struct {
24
	Path    string
25
	Span    token.Span
26
	Message string
27
}
28
29
type Date struct {
30
	Year, Month, Day int
31
	Sep              byte // '-' '/' '.'
32
	Span             token.Span
33
}
34
35
// Compare returns -1 if d is before other, 0 if equal, 1 if after.
36
func (d Date) Compare(other Date) int {
37
	if d.Year != other.Year {
38
		if d.Year < other.Year {
39
			return -1
40
		}
41
		return 1
42
	}
43
	if d.Month != other.Month {
44
		if d.Month < other.Month {
45
			return -1
46
		}
47
		return 1
48
	}
49
	if d.Day != other.Day {
50
		if d.Day < other.Day {
51
			return -1
52
		}
53
		return 1
54
	}
55
	return 0
56
}
57
58
type Time struct {
59
	Hour, Minute, Second int
60
	Span                 token.Span
61
}
62
63
type DateTime struct {
64
	Date Date
65
	Time *Time
66
	Span token.Span
67
}
68
69
type Tag struct {
70
	Key, Value string
71
	Span       token.Span
72
}
73
74
type Comment struct {
75
	Marker byte // ';' '#' '%' '*'
76
	Tags   []Tag
77
	Text   string
78
	Span   token.Span
79
}
80
81
func (Comment) entryNode() {}
82
83
type StatusType int
84
85
func (s StatusType) String() string {
86
	switch s {
87
	case StatusCleared:
88
		return "*"
89
	case StatusPending:
90
		return "!"
91
	case StatusNone:
92
		return ""
93
	default:
94
		panic("unreachable")
95
	}
96
}
97
98
const (
99
	StatusNone    StatusType = iota // not set
100
	StatusCleared                   // * cleared
101
	StatusPending                   // ! pending
102
)
103
104
type Status struct {
105
	Value StatusType
106
	Span  token.Span
107
}
108
109
type Code struct {
110
	Value string
111
	Span  token.Span
112
}
113
114
type Note struct {
115
	Value string
116
	Span  token.Span
117
}
118
119
type Description struct {
120
	Value string
121
	Span  token.Span
122
}
123
124
type Expr struct {
125
	Value string
126
	Span  token.Span
127
}
128
129
type Payee struct {
130
	Name string
131
	Span token.Span
132
}
133
134
type SubAccount struct {
135
	Name string
136
	Span token.Span
137
}
138
139
type Account struct {
140
	Name []SubAccount // ['expenses' 'food']
141
	Span token.Span
142
}
143
144
func (a Account) String() string {
145
	if len(a.Name) == 0 {
146
		return ""
147
	}
148
	var name strings.Builder
149
	name.Grow(len(a.Name))
150
	name.WriteString(a.Name[0].Name)
151
	for _, s := range a.Name[1:] {
152
		name.WriteByte(':')
153
		name.WriteString(s.Name)
154
	}
155
	return name.String()
156
}