Un-special-case parsing base."etc"
diff --git a/internal/cgen/expr.go b/internal/cgen/expr.go
index 7aa94e2..fa5ad27 100644
--- a/internal/cgen/expr.go
+++ b/internal/cgen/expr.go
@@ -38,6 +38,8 @@
b.writes("NULL")
} else if typ.IsStatus() {
b.writes("wuffs_base__make_status(NULL)")
+ } else if !typ.IsBool() {
+ return fmt.Errorf("cannot generate C expression for %v constant of type %q", n.Str(g.tm), n.MType().Str(g.tm))
} else if cv.Cmp(zero) == 0 {
b.writes("false")
} else if cv.Cmp(one) == 0 {
@@ -79,9 +81,9 @@
b.writes("wuffs_base__make_status(")
b.writes(z.cName)
b.writes(")")
- } else {
- return fmt.Errorf("unrecognized status %s", n.StatusQID().Str(g.tm))
+ return nil
}
+ return fmt.Errorf("unrecognized status %s", n.StatusQID().Str(g.tm))
} else if c, ok := g.scalarConstsMap[t.QID{0, n.Ident()}]; ok {
b.writes(c.Value().ConstValue().String())
@@ -212,6 +214,14 @@
b.writes(aPrefix)
b.writes(n.Ident().Str(g.tm))
return nil
+ } else if (lhs.Operator() == 0) && n.Ident().IsDQStrLiteral(g.tm) {
+ if z := g.statusMap[t.QID{lhs.Ident(), n.Ident()}]; z.cName != "" {
+ b.writes("wuffs_base__make_status(")
+ b.writes(z.cName)
+ b.writes(")")
+ return nil
+ }
+ return fmt.Errorf("unrecognized status %s", n.Str(g.tm))
}
if err := g.writeExpr(b, lhs, depth); err != nil {
@@ -317,10 +327,16 @@
func (g *gen) writeExprRepr(b *buffer, n *a.Expr, depth uint32) error {
isStatus := n.MType().IsStatus()
- if isStatus && (n.Operator() == 0) && n.Ident().IsDQStrLiteral(g.tm) {
- if z := g.statusMap[n.StatusQID()]; z.cName != "" {
- b.writes(z.cName)
- return nil
+ if isStatus {
+ if op := n.Operator(); ((op == 0) || (op == t.IDDot)) && n.Ident().IsDQStrLiteral(g.tm) {
+ qid := t.QID{0, n.Ident()}
+ if op == t.IDDot {
+ qid[0] = n.LHS().AsExpr().Ident()
+ }
+ if z := g.statusMap[qid]; z.cName != "" {
+ b.writes(z.cName)
+ return nil
+ }
}
}
if err := g.writeExpr(b, n, depth); err != nil {
diff --git a/internal/cgen/statement.go b/internal/cgen/statement.go
index fb6cd50..c0c1b8a 100644
--- a/internal/cgen/statement.go
+++ b/internal/cgen/statement.go
@@ -487,12 +487,10 @@
couldBeSuspension := false
if retExpr.MType().IsStatus() && !n.RetsError() {
couldBeSuspension = true
- if retExpr.Operator() == 0 {
- if id := retExpr.Ident(); id == t.IDOk {
- couldBeSuspension = false
- } else if s := g.tm.ByID(id); (len(s) > 1) && (s[0] == '"') {
- couldBeSuspension = s[1] == '$'
- }
+ if s := g.tm.ByID(retExpr.Ident()); (len(s) > 1) && (s[0] == '"') {
+ couldBeSuspension = s[1] == '$'
+ } else if (retExpr.Operator() == 0) && (retExpr.Ident() == t.IDOk) {
+ couldBeSuspension = false
}
}
diff --git a/lang/check/bounds.go b/lang/check/bounds.go
index d2bdc9f..0ce1f32 100644
--- a/lang/check/bounds.go
+++ b/lang/check/bounds.go
@@ -317,7 +317,7 @@
}
if lTyp.IsStatus() {
- if v := n.Value(); v.Operator() == 0 {
+ if v := n.Value(); (v.Operator() == 0) || (v.Operator() == t.IDDot) {
if id := v.Ident(); (id != t.IDOk) && (q.hasIsErrorFact(id) || isErrorStatus(id, q.tm)) {
n.SetRetsError()
}
diff --git a/lang/check/type.go b/lang/check/type.go
index 7f53b06..ac99f25 100644
--- a/lang/check/type.go
+++ b/lang/check/type.go
@@ -502,9 +502,12 @@
n.SetMType(c.XType())
return nil
}
- // TODO: look for other (global) names: consts, funcs, statuses,
- // structs from used packages.
- return fmt.Errorf("check: unrecognized identifier %q", qid.Str(q.tm))
+ if _, ok := q.c.statuses[t.QID{x, y}]; ok {
+ n.SetMType(typeExprStatus)
+ return nil
+ }
+ // TODO: look in q.c.structs.
+ return fmt.Errorf("check: unrecognized name %q", qid.Str(q.tm))
}
func (q *checker) tcheckExprCall(n *a.Expr, depth uint32) error {
diff --git a/lang/parse/parse.go b/lang/parse/parse.go
index 5dc7a43..52a9b23 100644
--- a/lang/parse/parse.go
+++ b/lang/parse/parse.go
@@ -1355,22 +1355,14 @@
case t.IDDot:
p.src = p.src[1:]
-
- if x := p.peek1(); x.IsLiteral(p.tm) {
- if !x.IsDQStrLiteral(p.tm) {
- return nil, fmt.Errorf(`parse: dot followed by non-"-string literal at %s:%d`, p.filename, p.line())
- }
- if !first {
- return nil, fmt.Errorf(`parse: "-string literal %s has too many package qualifiers at %s:%d`,
- x.Str(p.tm), p.filename, p.line())
- }
+ selector := p.peek1()
+ if first && selector.IsDQStrLiteral(p.tm) {
p.src = p.src[1:]
- return a.NewExpr(0, 0, id, x, nil, nil, nil, nil), nil
- }
-
- selector, err := p.parseIdent()
- if err != nil {
- return nil, err
+ } else {
+ selector, err = p.parseIdent()
+ if err != nil {
+ return nil, err
+ }
}
lhs = a.NewExpr(0, t.IDDot, 0, selector, lhs.AsNode(), nil, nil, nil)
}