Compare commits
9 Commits
main
...
dev-amery-
Author | SHA1 | Date |
---|---|---|
Alejandro Mery | 6df387ffeb | 1 year ago |
Alejandro Mery | 123770119e | 1 year ago |
Alejandro Mery | 667803fea5 | 1 year ago |
Alejandro Mery | a38f0c74e8 | 1 year ago |
Alejandro Mery | 7e0b7cfb47 | 1 year ago |
Alejandro Mery | fd4f6439b8 | 1 year ago |
Alejandro Mery | f74745471d | 1 year ago |
Alejandro Mery | 2b5dcec64d | 1 year ago |
Alejandro Mery | 4aa6233e4f | 1 year ago |
8 changed files with 218 additions and 20 deletions
@ -0,0 +1,2 @@ |
|||||||
|
// Package parser implements some common logic of asciigoat based parsers
|
||||||
|
package parser |
@ -0,0 +1,72 @@ |
|||||||
|
package parser |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"io" |
||||||
|
"strings" |
||||||
|
|
||||||
|
"asciigoat.org/core/lexer" |
||||||
|
) |
||||||
|
|
||||||
|
// TextParser ...
|
||||||
|
type TextParser struct { |
||||||
|
src *lexer.Reader |
||||||
|
pos lexer.Position |
||||||
|
} |
||||||
|
|
||||||
|
// Position ...
|
||||||
|
func (p *TextParser) Position() lexer.Position { |
||||||
|
return p.pos |
||||||
|
} |
||||||
|
|
||||||
|
// StepLine ...
|
||||||
|
func (p *TextParser) StepLine() { |
||||||
|
p.src.Discard() |
||||||
|
p.pos.StepLine() |
||||||
|
} |
||||||
|
|
||||||
|
// Step ...
|
||||||
|
func (p *TextParser) Step() { |
||||||
|
s := p.src.Emit() |
||||||
|
p.pos.StepN(len(s)) |
||||||
|
} |
||||||
|
|
||||||
|
// Emit ...
|
||||||
|
func (p *TextParser) Emit() Token { |
||||||
|
t := Token{ |
||||||
|
Value: p.src.Emit(), |
||||||
|
Position: p.pos, |
||||||
|
} |
||||||
|
|
||||||
|
p.pos.StepN(t.Len()) |
||||||
|
return t |
||||||
|
} |
||||||
|
|
||||||
|
// Peek ...
|
||||||
|
func (p *TextParser) Peek() string { |
||||||
|
return p.src.String() |
||||||
|
} |
||||||
|
|
||||||
|
// NewTextParser ...
|
||||||
|
func NewTextParser(r io.Reader) *TextParser { |
||||||
|
if r == nil { |
||||||
|
r = strings.NewReader("") |
||||||
|
} |
||||||
|
|
||||||
|
p := &TextParser{ |
||||||
|
src: lexer.NewReader(r), |
||||||
|
} |
||||||
|
p.pos.Reset() |
||||||
|
|
||||||
|
return p |
||||||
|
} |
||||||
|
|
||||||
|
// NewTextParserBytes ...
|
||||||
|
func NewTextParserBytes(b []byte) *TextParser { |
||||||
|
return NewTextParser(bytes.NewReader(b)) |
||||||
|
} |
||||||
|
|
||||||
|
// NewTextParserString ...
|
||||||
|
func NewTextParserString(s string) *TextParser { |
||||||
|
return NewTextParser(strings.NewReader(s)) |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package parser |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
|
||||||
|
"asciigoat.org/core/lexer" |
||||||
|
) |
||||||
|
|
||||||
|
// Token ...
|
||||||
|
type Token struct { |
||||||
|
lexer.Position |
||||||
|
|
||||||
|
Type uint |
||||||
|
Value string |
||||||
|
} |
||||||
|
|
||||||
|
// Len ...
|
||||||
|
func (t Token) Len() int { |
||||||
|
return len(t.Value) |
||||||
|
} |
||||||
|
|
||||||
|
// String generates the '%v' value
|
||||||
|
func (t Token) String() string { |
||||||
|
return t.Value |
||||||
|
} |
||||||
|
|
||||||
|
// GoString generates the '%#v' value
|
||||||
|
func (t Token) GoString() string { |
||||||
|
return fmt.Sprintf("Token{Position{%v,%v}, %v, %q}", |
||||||
|
t.Line, t.Column, t.Type, t.Value) |
||||||
|
} |
@ -0,0 +1,2 @@ |
|||||||
|
// Package reflective assists reflection-driven unmarshalling
|
||||||
|
package reflective |
@ -0,0 +1,69 @@ |
|||||||
|
package reflective |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"fmt" |
||||||
|
"reflect" |
||||||
|
) |
||||||
|
|
||||||
|
// An InvalidUnmarshalError describes an invalid argument passed to New.
|
||||||
|
// (It must be a non-nil pointer.)
|
||||||
|
type InvalidUnmarshalError struct { |
||||||
|
Method string |
||||||
|
Prefix string |
||||||
|
|
||||||
|
reflect.Type |
||||||
|
} |
||||||
|
|
||||||
|
func (e *InvalidUnmarshalError) Error() string { |
||||||
|
var buf bytes.Buffer |
||||||
|
|
||||||
|
if e.Prefix != "" { |
||||||
|
_, _ = fmt.Fprintf(&buf, "%s: ", e.Prefix) |
||||||
|
} |
||||||
|
|
||||||
|
method := e.Method |
||||||
|
if method == "" { |
||||||
|
method = "New" |
||||||
|
} |
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(&buf, "%s(", method) |
||||||
|
|
||||||
|
switch { |
||||||
|
case e.Type == nil: |
||||||
|
_, _ = buf.WriteString("nil") |
||||||
|
case e.Type.Kind() != reflect.Pointer: |
||||||
|
_, _ = fmt.Fprintf(&buf, "%s %s", "non-pointer", e.Type.String()) |
||||||
|
default: |
||||||
|
_, _ = fmt.Fprintf(&buf, "%s %s", "nil", e.Type.String()) |
||||||
|
} |
||||||
|
|
||||||
|
_, _ = buf.WriteString(")") |
||||||
|
|
||||||
|
return buf.String() |
||||||
|
} |
||||||
|
|
||||||
|
// An UnmarshalTypeError tells something went wrong while processing
|
||||||
|
// a type.
|
||||||
|
type UnmarshalTypeError struct { |
||||||
|
Prefix string |
||||||
|
Err error |
||||||
|
|
||||||
|
reflect.Type |
||||||
|
} |
||||||
|
|
||||||
|
func (e UnmarshalTypeError) Unwrap() error { |
||||||
|
return e.Err |
||||||
|
} |
||||||
|
|
||||||
|
func (e UnmarshalTypeError) Error() string { |
||||||
|
var buf bytes.Buffer |
||||||
|
|
||||||
|
if e.Prefix != "" { |
||||||
|
_, _ = fmt.Fprintf(&buf, "%s: ", e.Prefix) |
||||||
|
} |
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(&buf, "%s: %s", e.Type.String(), e.Err) |
||||||
|
|
||||||
|
return buf.String() |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package reflective |
||||||
|
|
||||||
|
import "reflect" |
||||||
|
|
||||||
|
// IsZero tells if a value is zero either via
|
||||||
|
// v.IsZero() or reflection.
|
||||||
|
func IsZero(iv any) bool { |
||||||
|
if p, ok := iv.(interface { |
||||||
|
IsZero() bool |
||||||
|
}); ok { |
||||||
|
return p.IsZero() |
||||||
|
} |
||||||
|
|
||||||
|
return reflect.ValueOf(iv).IsZero() |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package reflective |
||||||
|
|
||||||
|
import "reflect" |
||||||
|
|
||||||
|
// Reflection provides Marshalling/Unmarshalling oriented view
|
||||||
|
// of a value
|
||||||
|
type Reflection struct { |
||||||
|
v reflect.Value |
||||||
|
} |
||||||
|
|
||||||
|
// New creates a Reflection of the given pointer
|
||||||
|
func New(v any) (*Reflection, error) { |
||||||
|
rv := reflect.ValueOf(v) |
||||||
|
|
||||||
|
if rv.Kind() != reflect.Pointer || rv.IsNil() { |
||||||
|
err := &InvalidUnmarshalError{ |
||||||
|
Type: rv.Type(), |
||||||
|
} |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
r := &Reflection{ |
||||||
|
v: rv, |
||||||
|
} |
||||||
|
|
||||||
|
return r, nil |
||||||
|
} |
Loading…
Reference in new issue