package sema
import (
"github.com/marzeq/qk/parser"
"github.com/marzeq/qk/symbols"
)
func (a *Analyser) resolveIdentifier(n *parser.IdentifierNode) {
sym, ok := a.current.Resolve(n.Name)
if !ok {
a.errorf(n, "undefined identifier %q", n.Name)
return
}
n.Symbol = sym
}
func (a *Analyser) resolveModuleAccess(n *parser.ModuleAccessNode) (*symbols.Symbol, bool) {
if n.ModName == "" {
sym, ok := a.current.Resolve(n.Ident.Name)
if !ok {
a.errorf(n, "undefined identifier %q", n.Ident.Name)
return nil, false
}
n.Symbol = sym
return sym, true
}
modSym, ok := a.current.Resolve(n.ModName)
if !ok || modSym.Kind != symbols.SymbolKindModule {
a.errorf(n, "unknown module %q", n.ModName)
return nil, false
}
sym, ok := modSym.Module.Scope.Resolve(n.Ident.Name)
if !ok {
a.errorf(n, "undefined symbol %q in module %q", n.Ident.Name, n.ModName)
return nil, false
}
if !sym.Public && n.ModName != a.currentMod {
a.errorf(n, "symbol %q is not public in module %q", sym.Name, n.ModName)
return nil, false
}
n.Symbol = sym
return sym, true
}
func (a *Analyser) resolveFunctionCall(n *parser.FunctionCallNode) {
sym, ok := a.resolveModuleAccess(n.Name)
if !ok {
return
}
if sym.Kind != symbols.SymbolKindFunction {
a.errorf(n, "%q is not a function", sym.Name)
return
}
n.Symbol = sym
for _, arg := range n.Args {
a.visitExpression(arg)
}
}
func (a *Analyser) visitStructLiteral(n *parser.StructLiteralNode) {
if n.Name != nil {
sym, ok := a.resolveModuleAccess(n.Name)
if !ok {
return
}
if sym.Kind != symbols.SymbolKindType {
a.errorf(n, "%q is not a type", sym.Name)
return
}
n.Symbol = sym
}
for _, field := range n.Fields {
a.visitExpression(field.R)
}
}