diff options
| author | Marc Vertes <mvertes@free.fr> | 2025-03-03 10:49:27 +0100 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2025-03-03 10:49:27 +0100 |
| commit | ab69cd9ba61092650abdff6484b12021182385ce (patch) | |
| tree | 4805a0365fc481df57c8f0b5d45f7f993b9a0ef9 /parser/parse.go | |
| parent | dabd9e5eb81bbc9aeaeb32fb3e3ce83eef258a77 (diff) | |
fix: improve structparscan-struct
Use 'unsafe' to modify private struct fields, allowing to keep
unmodified field names: before they were prefixed with a capital.
Parse package statement. Provide a also a default package name for
REPL and tests. The support of packages is still incomplete.
Diffstat (limited to 'parser/parse.go')
| -rw-r--r-- | parser/parse.go | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/parser/parse.go b/parser/parse.go index 537b68e..2aa5ce7 100644 --- a/parser/parse.go +++ b/parser/parse.go @@ -20,6 +20,8 @@ type Parser struct { function *symbol scope string fname string + pkgName string // current package name + noPkg bool // true if package statement is not mandatory (test, repl). funcScope string framelen map[string]int // length of function frames indexed by funcScope @@ -38,6 +40,17 @@ var ( ErrGoto = errors.New("invalid goto statement") ) +// NewParser returns a new parser. +func NewParser(scanner *scanner.Scanner, noPkg bool) *Parser { + return &Parser{ + Scanner: scanner, + noPkg: noPkg, + symbols: initUniverse(), + framelen: map[string]int{}, + labelCount: map[string]int{}, + } +} + // Scan performs lexical analysis on s and returns Tokens or an error. func (p *Parser) Scan(s string, endSemi bool) (Tokens, error) { return p.Scanner.Scan(s, endSemi) @@ -84,6 +97,14 @@ func (p *Parser) parseStmt(in Tokens) (out Tokens, err error) { return nil, nil } log.Println("parseStmt in:", in) + // Preliminary: make sure that a pkgName is defined (or about to be). + if in[0].Tok != lang.Package && p.pkgName == "" { + if !p.noPkg { + return out, errors.New("no package defined") + } + p.pkgName = "main" + } + switch t := in[0]; t.Tok { case lang.Break: return p.parseBreak(in) @@ -104,7 +125,7 @@ func (p *Parser) parseStmt(in Tokens) (out Tokens, err error) { case lang.Import: return p.parseImports(in) case lang.Package: - // TODO: support packages + return p.parsePackage(in) return out, err case lang.Return: return p.parseReturn(in) @@ -263,7 +284,7 @@ func (p *Parser) parseFunc(in Tokens) (out Tokens, err error) { return out, err } s.kind = symFunc - s.Type = typ + s.typ = typ p.function = s toks, err := p.Parse(in[len(in)-1].Block()) @@ -459,8 +480,8 @@ func (p *Parser) parseReturn(in Tokens) (out Tokens, err error) { // TODO: the function symbol should be already present in the parser context. // otherwise no way to handle anonymous func. s := p.function - in[0].Beg = s.Type.Rtype.NumOut() - in[0].End = s.Type.Rtype.NumIn() + in[0].Beg = s.typ.Rtype.NumOut() + in[0].End = s.typ.Rtype.NumIn() out = append(out, in[0]) return out, err } |
