Skip to content

Commit

Permalink
调整 embed 特性, 仅支持 const
Browse files Browse the repository at this point in the history
  • Loading branch information
chai2010 committed Apr 19, 2024
1 parent c416461 commit 9596bd0
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 27 deletions.
8 changes: 6 additions & 2 deletions internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2391,9 +2391,13 @@ func (p *parser) parseValueSpec(doc *ast.CommentGroup, keyword token.Token, iota
p.error(pos, "missing variable type or initialization")
}
case token.CONST:
if values == nil && (iota == 0 || typ != nil) {
p.error(pos, "missing constant value")
if typ == nil && values == nil && iota == 0 {
p.error(pos, "missing const type or initialization")
}

// if values == nil && (iota == 0 || typ != nil) {
// p.error(pos, "missing constant value")
// }
}

// Go spec: The scope of a constant or variable identifier declared inside
Expand Down
4 changes: 2 additions & 2 deletions internal/types/decl.go
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ func (check *Checker) declStmt(decl ast.Decl) {
check.constDecl(obj, last.Type, init)
}

check.arityMatch(s, last)
check.arityMatch(s, last, false)

// process function literals in init expressions before scope changes
check.processDelayed(top)
Expand Down Expand Up @@ -657,7 +657,7 @@ func (check *Checker) declStmt(decl ast.Decl) {
}
}

check.arityMatch(s, nil)
check.arityMatch(s, nil, false)

// process function literals in init expressions before scope changes
check.processDelayed(top)
Expand Down
36 changes: 19 additions & 17 deletions internal/types/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,38 @@ import (

"wa-lang.org/wa/internal/ast"
"wa-lang.org/wa/internal/ast/astutil"
"wa-lang.org/wa/internal/constant"
"wa-lang.org/wa/internal/token"
)

// 预处理全局变量文件嵌入
func (check *Checker) processGlobalEmbed() {
for obj, d := range check.objMap {
if varObj, ok := obj.(*Var); ok {
varSpec := varObj.Node().(*ast.ValueSpec)
varCommentInfo := astutil.ParseCommentInfo(varObj.NodeDoc())
if constObj, ok := obj.(*Const); ok {
valueSpec := constObj.Node().(*ast.ValueSpec)
commentInfo := astutil.ParseCommentInfo(constObj.NodeDoc())

if varCommentInfo.Embed == "" {
if commentInfo.Embed == "" {
continue
}
if len(varSpec.Names) != 1 {
check.errorf(varObj.Pos(), "wa:embed only support one global")
if len(valueSpec.Names) != 1 {
check.errorf(constObj.Pos(), "wa:embed cannot apply to multiple const")
return
}
if len(varSpec.Values) != 0 || varSpec.Type == nil {
check.errorf(varObj.Pos(), "wa:embed donot support init values")
if len(valueSpec.Values) != 0 {
check.errorf(constObj.Pos(), "wa:embed cannot apply to const with initializer")
return
}

typeIdent, _ := varSpec.Type.(*ast.Ident)
typeIdent, _ := valueSpec.Type.(*ast.Ident)
if typeIdent == nil {
check.errorf(varObj.Pos(), "wa:embed must have type")
check.errorf(constObj.Pos(), "wa:embed cannot apply to untyped const")
return
}

scope, obj := check.pkg.scope.LookupParent(typeIdent.Name, varSpec.Pos())
scope, obj := check.pkg.scope.LookupParent(typeIdent.Name, valueSpec.Pos())
if scope != Universe || obj.Type() != universeString {
check.errorf(varObj.Pos(), "wa:embed invalid global type %v", obj)
check.errorf(constObj.Pos(), "wa:embed invalid global type %v", obj)
continue
}

Expand All @@ -47,27 +48,28 @@ func (check *Checker) processGlobalEmbed() {
Loop:
for _, f := range check.files {
for k, v := range f.EmbedMap {
if k == varCommentInfo.Embed {
if k == commentInfo.Embed {
embedFound = true
embedData = v
break Loop
}
}
}
if !embedFound {
check.errorf(varObj.Pos(), "wa:embed file not found")
check.errorf(constObj.Pos(), "wa:embed %s: not found no matching files found", commentInfo.Embed)
continue
}

varSpec.Values = []ast.Expr{
valueSpec.Values = []ast.Expr{
&ast.BasicLit{
ValuePos: varSpec.Pos(),
ValuePos: valueSpec.Pos(),
Kind: token.STRING,
Value: strconv.Quote(embedData),
},
}

d.init = varSpec.Values[0]
constObj.val = constant.MakeString(strconv.Quote(embedData))
d.init = valueSpec.Values[0]
}
}
}
18 changes: 13 additions & 5 deletions internal/types/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (d *declInfo) addDep(obj Object) {
// have the appropriate number of names and init exprs. For const
// decls, init is the value spec providing the init exprs; for
// var decls, init is nil (the init exprs are in s in this case).
func (check *Checker) arityMatch(s, init *ast.ValueSpec) {
func (check *Checker) arityMatch(s, init *ast.ValueSpec, hasEmbed bool) {
l := len(s.Names)
r := len(s.Values)
if init != nil {
Expand All @@ -79,8 +79,10 @@ func (check *Checker) arityMatch(s, init *ast.ValueSpec) {
// TODO(gri) avoid declared but not used error here
}
case l > r && (init != nil || r != 1):
n := s.Names[r]
check.errorf(n.Pos(), "missing init expr for %s", n)
if !hasEmbed {
n := s.Names[r]
check.errorf(n.Pos(), "missing init expr for %s", n)
}
}
}

Expand Down Expand Up @@ -325,6 +327,12 @@ func (check *Checker) collectObjects() {
case *ast.ValueSpec:
switch d.Tok {
case token.CONST:
hasEmbed := false
if len(s.Names) == 1 {
info := astutil.ParseCommentInfo(d.Doc)
hasEmbed = info.Embed != ""
}

// determine which initialization expressions to use
switch {
case s.Type != nil || len(s.Values) > 0:
Expand Down Expand Up @@ -353,7 +361,7 @@ func (check *Checker) collectObjects() {
check.declarePkgObj(name, obj, d)
}

check.arityMatch(s, last)
check.arityMatch(s, last, hasEmbed)

case token.VAR, token.GLOBAL:
lhs := make([]*Var, len(s.Names))
Expand Down Expand Up @@ -394,7 +402,7 @@ func (check *Checker) collectObjects() {
check.declarePkgObj(name, obj, d)
}

check.arityMatch(s, nil)
check.arityMatch(s, nil, false)

default:
check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
Expand Down
2 changes: 1 addition & 1 deletion waroot/src/apple/embed.wa
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 版权 @2023 凹语言 作者。保留所有权利。

#wa:embed logo.txt
global WaLogo: string
const WaLogo: string

0 comments on commit 9596bd0

Please sign in to comment.