From b3807a6ec3f3d463ae7173b1aa25c8537cf10f0a Mon Sep 17 00:00:00 2001 From: mertcandav Date: Thu, 1 Aug 2024 22:07:18 +0300 Subject: [PATCH] sema: minor optimizations for symbol lookup --- std/jule/internal/mod/export.jule | 17 ++++++++++++++ std/jule/internal/mod/mod.jule | 2 +- std/jule/parser/parser.jule | 24 ++++++++------------ std/jule/sema/eval.jule | 34 +++++++++++++++------------- std/jule/sema/sema.jule | 37 +++++++++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 31 deletions(-) create mode 100644 std/jule/internal/mod/export.jule diff --git a/std/jule/internal/mod/export.jule b/std/jule/internal/mod/export.jule new file mode 100644 index 000000000..0f7dedd08 --- /dev/null +++ b/std/jule/internal/mod/export.jule @@ -0,0 +1,17 @@ +// Copyright 2024 The Jule Programming Language. +// Use of this source code is governed by a BSD 3-Clause +// license that can be found in the LICENSE file. + +use utf8 for std::unicode::utf8 +use unicode for std::unicode +use nosafe for std::internal::nosafe + +// Reports whether identifier is public. +fn IsPub(&ident: str): bool { + if ident[0] < utf8::RuneSelf { // ASCII, fast way. + let b = ident[0] + ret 'A' <= b && b <= 'Z' + } + let (r, _) = utf8::DecodeRune(nosafe::Stobs(ident)) + ret unicode::IsUpper(r) +} \ No newline at end of file diff --git a/std/jule/internal/mod/mod.jule b/std/jule/internal/mod/mod.jule index a80a6532f..d05d1143b 100644 --- a/std/jule/internal/mod/mod.jule +++ b/std/jule/internal/mod/mod.jule @@ -43,7 +43,7 @@ fn FindModuleFileDeep(mut path: str): str { } // Checks module file of given directory. -fn CheckModuleFile(path: str): []Log { +fn CheckModuleFile(&path: str): []Log { let bytes = File.Read(path::Join(path, build::ModuleFile)) else { ret [{ Kind: LogKind.Flat, diff --git a/std/jule/parser/parser.jule b/std/jule/parser/parser.jule index 1bc953c89..461e8614b 100644 --- a/std/jule/parser/parser.jule +++ b/std/jule/parser/parser.jule @@ -45,9 +45,8 @@ use std::jule::build::{ Logf, IsTopDirective, } +use mod for std::jule::internal::mod use strings for std::strings -use utf8 for std::unicode::utf8 -use unicode for std::unicode fn makeErr(row: int, col: int, &f: &File, fmt: LogMsg, args: ...any): Log { ret Log{ @@ -344,7 +343,7 @@ impl parser { if ok && i < len(tokens) { self.pushErr(tokens[i], LogMsg.InvalidSyntax) } - tad.Public = isPub(tad.Ident) + tad.Public = mod::IsPub(tad.Ident) ret tad } @@ -388,7 +387,7 @@ impl parser { ret } v.Ident = v.Token.Kind - v.Public = isPub(v.Ident) + v.Public = mod::IsPub(v.Ident) v.Kind = nil // For auto-type. if len(tokens) > 1 { tokens = tokens[1:] // Remove identifier. @@ -859,7 +858,7 @@ impl parser { } } - f.Public = isPub(f.Ident) + f.Public = mod::IsPub(f.Ident) f.Result, _ = self.buildRetType(tokens, i) ret f } @@ -1170,7 +1169,7 @@ impl parser { } else if i < len(tokens) { self.pushErr(tokens[i], LogMsg.InvalidSyntax) } - e.Public = isPub(e.Ident) + e.Public = mod::IsPub(e.Ident) e.End = tokens[i-1] e.Items = self.buildTypeEnumItems(itemTokens) ret e @@ -1284,7 +1283,7 @@ impl parser { } else if i < len(tokens) { self.pushErr(tokens[i], LogMsg.InvalidSyntax) } - e.Public = isPub(e.Ident) + e.Public = mod::IsPub(e.Ident) e.End = tokens[i-1] e.Items = self.buildEnumItems(itemTokens) ret e @@ -1344,7 +1343,7 @@ impl parser { tokens = tokens[i:] f.Default = self.buildExpr(tokens) } - f.Public = isPub(f.Ident) + f.Public = mod::IsPub(f.Ident) ret f } @@ -1401,7 +1400,7 @@ impl parser { if i < len(tokens) { self.pushErr(tokens[i], LogMsg.InvalidSyntax) } - s.Public = isPub(s.Ident) + s.Public = mod::IsPub(s.Ident) s.Fields = self.buildStructDeclFields(bodyTokens) s.End = tokens[i-1] ret s @@ -1482,7 +1481,7 @@ impl parser { if i < len(tokens) { self.pushErr(tokens[i], LogMsg.InvalidSyntax) } - t.Public = isPub(t.Ident) + t.Public = mod::IsPub(t.Ident) self.buildTraitBody(t, bodyTokens) t.End = tokens[i-1] ret t @@ -1948,9 +1947,4 @@ impl parser { self.pushErr(self.directives[0].Tag, LogMsg.UnusedDirective) } } -} - -fn isPub(&ident: str): bool { - let (r, _) = utf8::DecodeRuneStr(ident) - ret unicode::IsUpper(r) } \ No newline at end of file diff --git a/std/jule/sema/eval.jule b/std/jule/sema/eval.jule index b5fc86b6b..3bbb8e749 100644 --- a/std/jule/sema/eval.jule +++ b/std/jule/sema/eval.jule @@ -55,6 +55,7 @@ use lex for std::jule::lex::{ IsIgnoreIdent, } use types for std::jule::types +use mod for std::jule::internal::mod use strings for std::strings // Value data. @@ -326,22 +327,25 @@ impl Eval { } fn findBuiltins(mut self, &ident: str): any { - match type self.lookup { - | &ImportInfo: - let mut def = findBuiltinsImport(ident, (&ImportInfo)(self.lookup)) - if def != nil { - ret def - } - | &Sema: - let mut def = findBuiltinsSema(ident, (&Sema)(self.lookup)) - if def != nil { - ret def - } - | &scopeChecker: - let mut def = findBuiltinsSema(ident, (&scopeChecker)(self.lookup).s) - if def != nil { - ret def + if mod::IsPub(ident) { + match type self.lookup { + | &ImportInfo: + let mut def = findBuiltinsImport(ident, (&ImportInfo)(self.lookup)) + if def != nil { + ret def + } + | &Sema: + let mut def = findBuiltinsSema(ident, (&Sema)(self.lookup)) + if def != nil { + ret def + } + | &scopeChecker: + let mut def = findBuiltinsSema(ident, (&scopeChecker)(self.lookup).s) + if def != nil { + ret def + } } + ret nil } if self.disBuiltin { ret nil diff --git a/std/jule/sema/sema.jule b/std/jule/sema/sema.jule index 9e195612b..a5e3d8edd 100644 --- a/std/jule/sema/sema.jule +++ b/std/jule/sema/sema.jule @@ -6,6 +6,7 @@ use ast for std::jule::ast use build for std::jule::build::{Directive, Derive, LogMsg, Log, LogKind, Logf} use std::jule::constant::{Const} use std::jule::lex::{File, Token, TokenId, TokenKind, IsIgnoreIdent, IsAnonIdent} +use mod for std::jule::internal::mod use types for std::jule::types use strings for std::strings @@ -256,6 +257,11 @@ impl Lookup for Sema { ret v } + // If identifier is not public, it should be built-in or package define. + if !mod::IsPub(ident) { + ret nil + } + // Lookup current file's public denifes of imported packages. for (_, mut imp) in self.file.Imports { if !impIsLookupable(imp, ident) { @@ -283,6 +289,11 @@ impl Lookup for Sema { ret ta } + // If identifier is not public, it should be built-in or package define. + if !mod::IsPub(ident) { + ret nil + } + // Lookup current file's public denifes of imported packages. for (_, mut imp) in self.file.Imports { if !impIsLookupable(imp, ident) { @@ -309,6 +320,12 @@ impl Lookup for Sema { if s != nil { ret s } + + // If identifier is not public, it should be built-in or package define. + if !mod::IsPub(ident) { + ret nil + } + // Lookup current file's public denifes of imported packages. for (_, mut imp) in self.file.Imports { if !impIsLookupable(imp, ident) { @@ -335,6 +352,11 @@ impl Lookup for Sema { ret f } + // If identifier is not public, it should be built-in or package define. + if !mod::IsPub(ident) { + ret nil + } + // Lookup current file's public denifes of imported packages. for (_, mut imp) in self.file.Imports { if !impIsLookupable(imp, ident) { @@ -362,6 +384,11 @@ impl Lookup for Sema { ret t } + // If identifier is not public, it should be built-in or package define. + if !mod::IsPub(ident) { + ret nil + } + // Lookup current file's public denifes of imported packages. for (_, mut imp) in self.file.Imports { if !impIsLookupable(imp, ident) { @@ -389,6 +416,11 @@ impl Lookup for Sema { ret e } + // If identifier is not public, it should be built-in or package define. + if !mod::IsPub(ident) { + ret nil + } + // Lookup current file's public denifes of imported packages. for (_, mut imp) in self.file.Imports { if !impIsLookupable(imp, ident) { @@ -416,6 +448,11 @@ impl Lookup for Sema { ret e } + // If identifier is not public, it should be built-in or package define. + if !mod::IsPub(ident) { + ret nil + } + // Lookup current file's public denifes of imported packages. for (_, mut imp) in self.file.Imports { if !impIsLookupable(imp, ident) {