GitFiend / gitfiend2

Experiment to simply things
2 stars 0 forks source link

alpha or beta release? #1

Open sjoerdev opened 2 months ago

sjoerdev commented 2 months ago

can we get a prerelease build to try? that way we can test and help,

GitFiend commented 2 months ago

At the moment i'm just building a server and will be comparing results with the existing implementation to avoid regressions. After that, I'll be working on the app shell. Happy to make prerelease builds at that point.

cdwmhcc commented 2 months ago
func And6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](p1 Parser[T1], p2 Parser[T2], p3 Parser[T3], p4 Parser[T4], p5 Parser[T5], p6 Parser[T6]) Parser[And6Result[T1, T2, T3, T4, T5, T6]] {
    return func(in *Input) (And6Result[T1, T2, T3, T4, T5, T6], bool) {
        start := in.Position

        res1, ok1 := p1(in)
        if ok1 {
            res2, ok2 := p2(in)
            if ok2 {
                res3, ok3 := p3(in)
                if ok3 {
                    res4, ok4 := p4(in)
                    if ok4 {
                        res5, ok5 := p5(in)
                        if ok5 {
                            res6, ok6 := p6(in)
                            if ok6 {
                                return And6Result[T1, T2, T3, T4, T5, T6]{
                                    R1: res1,
                                    R2: res2,
                                    R3: res3,
                                    R4: res4,
                                    R5: res5,
                                    R6: res6,
                                }, true
                            }
                        }
                    }
                }
            }
        }
        in.SetPosition(start)
        return And6Result[T1, T2, T3, T4, T5, T6]{}, false
    }
}
type ParserFunc[T any] func(in *Input) (T, bool)

func And6[T1, T2, T3, T4, T5, T6 any](p1 Parser[T1], p2 Parser[T2], p3 Parser[T3], p4 Parser[T4], p5 Parser[T5], p6 Parser[T6]) Parser[And6Result[T1, T2, T3, T4, T5, T6]] {
    return func(in *Input) (And6Result[T1, T2, T3, T4, T5, T6], bool) {
        start := in.Position
        results := make([]any, 6)

        parsers := []ParserFunc[any]{
            func(in *Input) (any, bool) { return p1(in) },
            func(in *Input) (any, bool) { return p2(in) },
            func(in *Input) (any, bool) { return p3(in) },
            func(in *Input) (any, bool) { return p4(in) },
            func(in *Input) (any, bool) { return p5(in) },
            func(in *Input) (any, bool) { return p6(in) },
        }

        for i, parse := range parsers {
            result, ok := parse(in)
            if !ok {
                in.SetPosition(start)
                return And6Result[T1, T2, T3, T4, T5, T6]{}, false
            }
            results[i] = result
        }

        return And6Result[T1, T2, T3, T4, T5, T6]{
            R1: results[0].(T1),
            R2: results[1].(T2),
            R3: results[2].(T3),
            R4: results[3].(T4),
            R5: results[4].(T5),
            R6: results[5].(T6),
        }, true
    }
}
GitFiend commented 2 months ago

@cdwmhcc Your suggested version is nicer in that it reduces the nesting, but this is generated code (See core/parser/genand/main.go) and I suspect your version would run slower due to array creation, loop and casting back to the result type. Someone only really needs to look at the first couple of versions to get the gist, so I don't think readability is much of a concern other than the core concept of the parser is tricky.