summaryrefslogtreecommitdiff
path: root/parser/parse.go
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-03-03 10:49:27 +0100
committerMarc Vertes <mvertes@free.fr>2025-03-03 10:49:27 +0100
commitab69cd9ba61092650abdff6484b12021182385ce (patch)
tree4805a0365fc481df57c8f0b5d45f7f993b9a0ef9 /parser/parse.go
parentdabd9e5eb81bbc9aeaeb32fb3e3ce83eef258a77 (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.go29
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
}