nicer but my fsm is wrong if i want to bundle ands first
cicd / ci (push) Successful in 3m29s Details

main
Bel LaPointe 2024-12-13 10:49:19 -07:00
parent 012024ac66
commit d7edc1ff1d
2 changed files with 78 additions and 90 deletions

View File

@ -40,31 +40,10 @@ func Main() {
}
cmd := positional[0]
q, err := BuildQuery(positional)
q, err := BuildQuery(positional[1:])
if err != nil {
panic(err)
}
panic(q)
likePattern := ""
notLikePattern := ""
i := 1
for i < len(positional) {
switch positional[i] {
case "not":
_ = notLikePattern
panic(positional[i:])
case "and":
panic(positional[i:])
default:
if likePattern == "" {
likePattern = positional[i]
} else {
likePattern = fmt.Sprintf("%s|%s", likePattern, positional[i])
}
}
i += 1
}
deltas, err := ledgerFiles.Deltas()
if err != nil {
@ -86,37 +65,22 @@ func Main() {
switch cmd[:3] {
case "bal":
balances := deltas.Balances()
if likePattern != "" {
balances = balances.Like(likePattern)
}
if notLikePattern != "" {
balances = balances.NotLike(notLikePattern)
}
/*
balances := deltas.Balances()
if likePattern != "" {
balances = balances.Like(likePattern)
}
if notLikePattern != "" {
balances = balances.NotLike(notLikePattern)
}
FPrintBalances(os.Stdout, "", balances, nil)
FPrintBalances(os.Stdout, "", balances, nil)
*/
case "reg":
transactions := deltas.Transactions()
likes := []ledger.Like{}
if likePattern != "" {
like := ledger.LikeName(likePattern)
transactions = transactions.Like(like)
if config.Query.Reverse {
like = ledger.LikeNot(like)
}
likes = append(likes, like)
}
if notLikePattern != "" {
like := ledger.NotLikeName(notLikePattern)
transactions = transactions.NotLike(like)
if config.Query.Reverse {
like = ledger.LikeNot(like)
}
likes = append(likes, like)
}
for i, transaction := range transactions {
balances := ledger.Deltas(transaction).Like(likes...).Balances()
balances := ledger.Deltas(transaction).Like(q).Balances()
shouldPrint := false
shouldPrint = shouldPrint || len(balances) > 2
if config.Query.NoExchanging {
@ -129,7 +93,7 @@ func Main() {
}
if shouldPrint {
fmt.Printf("%s\t%s\n", transaction[0].Date, transaction[0].Description)
FPrintBalances(os.Stdout, "\t\t", balances, transactions[:i+1].Deltas().Like(likes...).Balances())
FPrintBalances(os.Stdout, "\t\t", balances, transactions[:i+1].Deltas().Like(q).Balances())
}
}
default:

View File

@ -2,7 +2,7 @@ package cli
import (
"fmt"
"io"
"log"
"gogs.inhome.blapointe.com/ana-ledger/src/ledger"
)
@ -10,67 +10,91 @@ import (
type Query struct{}
func BuildQuery(args args) (ledger.Like, error) {
likes := make(ledger.Likes, 0)
for _, ok := args.peek(); ok; _, ok = args.peek() {
like, err := buildOneQuery(args)
if err != nil {
return nil, err
}
likes = append(likes, like)
}
return likes.Any, nil
var result ledger.Like
var err error
func() {
defer func() {
if err := recover(); err != nil {
err = fmt.Errorf("panicked: %v", err)
}
}()
result, err = buildQuery(args)
}()
return result, err
}
func buildOneQuery(args args) (ledger.Like, error) {
word, ok := args.peek()
if !ok {
return nil, io.EOF
func buildQuery(args args) (ledger.Like, error) {
likeName := func(s string) ledger.Like {
return ledger.LikeName(s)
}
andLike := func(a, b ledger.Like) ledger.Like {
return (ledger.Likes{a, b}).All
}
orLike := func(a, b ledger.Like) ledger.Like {
return (ledger.Likes{a, b}).Any
}
notLike := func(a ledger.Like) ledger.Like {
return ledger.LikeNot(a)
}
likes := make(ledger.Likes, 0)
if !args.more() {
return likeName(""), nil
}
like := likeName("ajskfdlsjfkdasj")
for _, ok := args.peek(); ok; _, ok = args.peek() {
switch word {
for args.more() {
switch args.peek() {
case "and":
if len(likes) == 0 {
return nil, fmt.Errorf("and without predicate")
}
args.pop()
like, err := buildOneQuery(args)
if err != nil {
return nil, err
var like ledger.Like
switch args.peek() {
case "not":
args.pop()
log.Println("and not", args.peek())
like = notLike(likeName(args.pop()))
default:
log.Println("and ", args.peek())
like = likeName(args.pop())
}
likes = append(likes, like)
like = andLike(like, like)
case "not":
args.pop()
like, err := buildOneQuery(args)
if err != nil {
return nil, err
}
likes = append(likes, like)
log.Println("or not ", args.peek())
like = orLike(like, notLike(
likeName(args.pop()),
))
default:
return nil, io.EOF
if next, _ := args.peek(); next != "and" {
return likes.All, nil
}
log.Println("or ", args.peek())
like = orLike(like,
likeName(args.pop()),
)
}
}
return nil, io.EOF
return like, nil
}
type args []string
func (args *args) pop() string {
first := (*args)[0]
*args = (*args)[1:]
if !args.more() {
panic("expected more arguments")
}
first := ""
if len(*args) > 0 {
first = (*args)[0]
*args = (*args)[1:]
}
return first
}
func (args *args) peek() (string, bool) {
func (args *args) peek() string {
if len(*args) == 0 {
return "", false
return ""
}
return (*args)[0], true
return (*args)[0]
}
func (args *args) more() bool {
return len(*args) > 0
}