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) { 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) } }