compiler: rename pkg to mod and auto save file import table
parent
5939238655
commit
01c2d25ae5
|
@ -14,7 +14,7 @@ struct Fn {
|
||||||
// addr int
|
// addr int
|
||||||
mut:
|
mut:
|
||||||
name string
|
name string
|
||||||
pkg string
|
mod string
|
||||||
local_vars []Var
|
local_vars []Var
|
||||||
var_idx int
|
var_idx int
|
||||||
args []Var
|
args []Var
|
||||||
|
@ -97,9 +97,9 @@ fn (p mut Parser) is_sig() bool {
|
||||||
(p.file_path.contains(ModPath))
|
(p.file_path.contains(ModPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_fn(pkg string, is_public bool) *Fn {
|
fn new_fn(mod string, is_public bool) *Fn {
|
||||||
return &Fn {
|
return &Fn {
|
||||||
pkg: pkg
|
mod: mod
|
||||||
local_vars: [Var{} ; MaxLocalVars]
|
local_vars: [Var{} ; MaxLocalVars]
|
||||||
is_public: is_public
|
is_public: is_public
|
||||||
}
|
}
|
||||||
|
@ -137,13 +137,13 @@ fn (p mut Parser) fn_decl() {
|
||||||
p.error('invalid receiver type `$receiver_typ` (`$receiver_typ` is an interface)')
|
p.error('invalid receiver type `$receiver_typ` (`$receiver_typ` is an interface)')
|
||||||
}
|
}
|
||||||
// Don't allow modifying types from a different module
|
// Don't allow modifying types from a different module
|
||||||
if !p.first_pass() && !p.builtin_pkg && T.mod != p.mod {
|
if !p.first_pass() && !p.builtin_mod && T.mod != p.mod {
|
||||||
println('T.mod=$T.mod')
|
println('T.mod=$T.mod')
|
||||||
println('p.mod=$p.mod')
|
println('p.mod=$p.mod')
|
||||||
p.error('cannot define new methods on non-local type `$receiver_typ`')
|
p.error('cannot define new methods on non-local type `$receiver_typ`')
|
||||||
}
|
}
|
||||||
// (a *Foo) instead of (a mut Foo) is a common mistake
|
// (a *Foo) instead of (a mut Foo) is a common mistake
|
||||||
if !p.builtin_pkg && receiver_typ.contains('*') {
|
if !p.builtin_mod && receiver_typ.contains('*') {
|
||||||
t := receiver_typ.replace('*', '')
|
t := receiver_typ.replace('*', '')
|
||||||
p.error('use `($receiver_name mut $t)` instead of `($receiver_name *$t)`')
|
p.error('use `($receiver_name mut $t)` instead of `($receiver_name *$t)`')
|
||||||
}
|
}
|
||||||
|
@ -175,10 +175,10 @@ fn (p mut Parser) fn_decl() {
|
||||||
// C function header def? (fn C.NSMakeRect(int,int,int,int))
|
// C function header def? (fn C.NSMakeRect(int,int,int,int))
|
||||||
is_c := f.name == 'C' && p.tok == .dot
|
is_c := f.name == 'C' && p.tok == .dot
|
||||||
// Just fn signature? only builtin.v + default build mode
|
// Just fn signature? only builtin.v + default build mode
|
||||||
// is_sig := p.builtin_pkg && p.pref.build_mode == default_mode
|
// is_sig := p.builtin_mod && p.pref.build_mode == default_mode
|
||||||
// is_sig := p.pref.build_mode == default_mode && (p.builtin_pkg || p.file.contains(LANG_TMP))
|
// is_sig := p.pref.build_mode == default_mode && (p.builtin_mod || p.file.contains(LANG_TMP))
|
||||||
is_sig := p.is_sig()
|
is_sig := p.is_sig()
|
||||||
// println('\n\nfn decl !!is_sig=$is_sig name=$f.name $p.builtin_pkg')
|
// println('\n\nfn decl !!is_sig=$is_sig name=$f.name $p.builtin_mod')
|
||||||
if is_c {
|
if is_c {
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
f.name = p.check_name()
|
f.name = p.check_name()
|
||||||
|
@ -199,10 +199,10 @@ fn (p mut Parser) fn_decl() {
|
||||||
if receiver_typ != '' {
|
if receiver_typ != '' {
|
||||||
// f.name = '${receiver_typ}_${f.name}'
|
// f.name = '${receiver_typ}_${f.name}'
|
||||||
}
|
}
|
||||||
// full pkg function name
|
// full mod function name
|
||||||
// os.exit ==> os__exit()
|
// os.exit ==> os__exit()
|
||||||
if !is_c && !p.builtin_pkg && p.mod != 'main' && receiver_typ.len == 0 {
|
if !is_c && !p.builtin_mod && p.mod != 'main' && receiver_typ.len == 0 {
|
||||||
f.name = p.prepend_pkg(f.name)
|
f.name = p.prepend_mod(f.name)
|
||||||
}
|
}
|
||||||
if p.first_pass() && p.table.known_fn(f.name) && receiver_typ.len == 0 {
|
if p.first_pass() && p.table.known_fn(f.name) && receiver_typ.len == 0 {
|
||||||
existing_fn := p.table.find_fn(f.name)
|
existing_fn := p.table.find_fn(f.name)
|
||||||
|
@ -471,7 +471,7 @@ _thread_so = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&reload_so, 0, 0, 0);
|
||||||
// p.error('unclosed {')
|
// p.error('unclosed {')
|
||||||
}
|
}
|
||||||
// Make sure all vars in this function are used (only in main for now)
|
// Make sure all vars in this function are used (only in main for now)
|
||||||
// if p.builtin_pkg || p.mod == 'os' ||p.mod=='http'{
|
// if p.builtin_mod || p.mod == 'os' ||p.mod=='http'{
|
||||||
if p.mod != 'main' {
|
if p.mod != 'main' {
|
||||||
if !is_generic {
|
if !is_generic {
|
||||||
p.genln('}')
|
p.genln('}')
|
||||||
|
@ -580,11 +580,11 @@ fn (p mut Parser) async_fn_call(f Fn, method_ph int, receiver_var, receiver_type
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) fn_call(f Fn, method_ph int, receiver_var, receiver_type string) {
|
fn (p mut Parser) fn_call(f Fn, method_ph int, receiver_var, receiver_type string) {
|
||||||
if !f.is_public && !f.is_c && !p.pref.is_test && !f.is_interface && f.pkg != p.mod {
|
if !f.is_public && !f.is_c && !p.pref.is_test && !f.is_interface && f.mod != p.mod {
|
||||||
p.error('function `$f.name` is private')
|
p.error('function `$f.name` is private')
|
||||||
}
|
}
|
||||||
p.calling_c = f.is_c
|
p.calling_c = f.is_c
|
||||||
if f.is_c && !p.builtin_pkg {
|
if f.is_c && !p.builtin_mod {
|
||||||
if f.name == 'free' {
|
if f.name == 'free' {
|
||||||
p.error('use `free()` instead of `C.free()`')
|
p.error('use `free()` instead of `C.free()`')
|
||||||
} else if f.name == 'malloc' {
|
} else if f.name == 'malloc' {
|
||||||
|
|
|
@ -28,7 +28,7 @@ fn (p mut Parser) gen_json_for_type(typ Type) {
|
||||||
// println('gen_json_for_type( $typ.name )')
|
// println('gen_json_for_type( $typ.name )')
|
||||||
// Register decoder fn
|
// Register decoder fn
|
||||||
mut dec_fn := Fn {
|
mut dec_fn := Fn {
|
||||||
pkg: p.mod
|
mod: p.mod
|
||||||
typ: 'Option_$typ.name'
|
typ: 'Option_$typ.name'
|
||||||
name: js_dec_name(t)
|
name: js_dec_name(t)
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ fn (p mut Parser) gen_json_for_type(typ Type) {
|
||||||
p.table.register_fn(dec_fn)
|
p.table.register_fn(dec_fn)
|
||||||
// Register encoder fn
|
// Register encoder fn
|
||||||
mut enc_fn := Fn {
|
mut enc_fn := Fn {
|
||||||
pkg: p.mod
|
mod: p.mod
|
||||||
typ: 'cJSON*'
|
typ: 'cJSON*'
|
||||||
name: js_enc_name(t)
|
name: js_enc_name(t)
|
||||||
}
|
}
|
||||||
|
|
|
@ -946,19 +946,15 @@ fn (v mut V) add_v_files_to_compile() {
|
||||||
v.log('user_files:')
|
v.log('user_files:')
|
||||||
println(user_files)
|
println(user_files)
|
||||||
}
|
}
|
||||||
// import tables for user/lib files
|
|
||||||
mut file_imports := []FileImportTable
|
|
||||||
// Parse builtin imports
|
// Parse builtin imports
|
||||||
for file in v.files {
|
for file in v.files {
|
||||||
mut p := v.new_parser(file, Pass.imports)
|
mut p := v.new_parser(file, Pass.imports)
|
||||||
p.parse()
|
p.parse()
|
||||||
file_imports << *p.import_table
|
|
||||||
}
|
}
|
||||||
// Parse user imports
|
// Parse user imports
|
||||||
for file in user_files {
|
for file in user_files {
|
||||||
mut p := v.new_parser(file, Pass.imports)
|
mut p := v.new_parser(file, Pass.imports)
|
||||||
p.parse()
|
p.parse()
|
||||||
file_imports << *p.import_table
|
|
||||||
}
|
}
|
||||||
// Parse lib imports
|
// Parse lib imports
|
||||||
/*
|
/*
|
||||||
|
@ -977,7 +973,6 @@ fn (v mut V) add_v_files_to_compile() {
|
||||||
for file in vfiles {
|
for file in vfiles {
|
||||||
mut p := v.new_parser(file, Pass.imports)
|
mut p := v.new_parser(file, Pass.imports)
|
||||||
p.parse()
|
p.parse()
|
||||||
file_imports << *p.import_table
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,7 +991,6 @@ fn (v mut V) add_v_files_to_compile() {
|
||||||
for file in vfiles {
|
for file in vfiles {
|
||||||
mut p := v.new_parser(file, Pass.imports)
|
mut p := v.new_parser(file, Pass.imports)
|
||||||
p.parse()
|
p.parse()
|
||||||
file_imports << *p.import_table
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if v.pref.is_verbose {
|
if v.pref.is_verbose {
|
||||||
|
@ -1005,7 +999,7 @@ fn (v mut V) add_v_files_to_compile() {
|
||||||
}
|
}
|
||||||
// graph deps
|
// graph deps
|
||||||
mut dep_graph := new_mod_dep_graph()
|
mut dep_graph := new_mod_dep_graph()
|
||||||
dep_graph.from_import_tables(file_imports)
|
dep_graph.from_import_tables(v.table.file_imports)
|
||||||
deps_resolved := dep_graph.resolve()
|
deps_resolved := dep_graph.resolve()
|
||||||
if !deps_resolved.acyclic {
|
if !deps_resolved.acyclic {
|
||||||
deps_resolved.display()
|
deps_resolved.display()
|
||||||
|
@ -1034,7 +1028,7 @@ fn (v mut V) add_v_files_to_compile() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add remaining files (not modules)
|
// add remaining files (not modules)
|
||||||
for fit in file_imports {
|
for fit in v.table.file_imports {
|
||||||
//println('fit $fit.file_path')
|
//println('fit $fit.file_path')
|
||||||
if !fit.file_path in v.files {
|
if !fit.file_path in v.files {
|
||||||
v.files << fit.file_path
|
v.files << fit.file_path
|
||||||
|
@ -1058,13 +1052,13 @@ fn get_arg(joined_args, arg, def string) string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (v &V) module_path(pkg string) string {
|
fn (v &V) module_path(mod string) string {
|
||||||
// submodule support
|
// submodule support
|
||||||
if pkg.contains('.') {
|
if mod.contains('.') {
|
||||||
//return pkg.replace('.', path_sep)
|
//return mod.replace('.', path_sep)
|
||||||
return pkg.replace('.', '/')
|
return mod.replace('.', '/')
|
||||||
}
|
}
|
||||||
return pkg
|
return mod
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (v &V) log(s string) {
|
fn (v &V) log(s string) {
|
||||||
|
|
|
@ -62,7 +62,7 @@ mut:
|
||||||
tmp_cnt int
|
tmp_cnt int
|
||||||
is_script bool
|
is_script bool
|
||||||
pref *Preferences // Setting and Preferences shared from V struct
|
pref *Preferences // Setting and Preferences shared from V struct
|
||||||
builtin_pkg bool
|
builtin_mod bool
|
||||||
vh_lines []string
|
vh_lines []string
|
||||||
inside_if_expr bool
|
inside_if_expr bool
|
||||||
is_struct_init bool
|
is_struct_init bool
|
||||||
|
@ -184,13 +184,13 @@ fn (p mut Parser) parse() {
|
||||||
p.mod = p.check_name()
|
p.mod = p.check_name()
|
||||||
}
|
}
|
||||||
p.fgenln('\n')
|
p.fgenln('\n')
|
||||||
p.builtin_pkg = p.mod == 'builtin'
|
p.builtin_mod = p.mod == 'builtin'
|
||||||
p.can_chash = p.mod == 'ft' || p.mod == 'glfw' || p.mod=='glfw2' || p.mod=='ui' // TODO tmp remove
|
p.can_chash = p.mod == 'ft' || p.mod == 'glfw' || p.mod=='glfw2' || p.mod=='ui' // TODO tmp remove
|
||||||
// Import pass - the first and the smallest pass that only analyzes imports
|
// Import pass - the first and the smallest pass that only analyzes imports
|
||||||
// fully qualify the module name, eg base64 to encoding.base64
|
// fully qualify the module name, eg base64 to encoding.base64
|
||||||
fq_mod := p.table.qualify_module(p.mod, p.file_path)
|
fq_mod := p.table.qualify_module(p.mod, p.file_path)
|
||||||
p.import_table.module_name = fq_mod
|
p.import_table.module_name = fq_mod
|
||||||
p.table.register_package(fq_mod)
|
p.table.register_module(fq_mod)
|
||||||
// replace "." with "_dot_" in module name for C variable names
|
// replace "." with "_dot_" in module name for C variable names
|
||||||
p.mod = fq_mod.replace('.', '_dot_')
|
p.mod = fq_mod.replace('.', '_dot_')
|
||||||
if p.pass == .imports {
|
if p.pass == .imports {
|
||||||
|
@ -200,6 +200,8 @@ fn (p mut Parser) parse() {
|
||||||
if p.table.imports.contains('builtin') {
|
if p.table.imports.contains('builtin') {
|
||||||
p.error('module `builtin` cannot be imported')
|
p.error('module `builtin` cannot be imported')
|
||||||
}
|
}
|
||||||
|
// save file import table
|
||||||
|
p.table.file_imports << *p.import_table
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Go through every top level token or throw a compilation error if a non-top level token is met
|
// Go through every top level token or throw a compilation error if a non-top level token is met
|
||||||
|
@ -264,7 +266,7 @@ fn (p mut Parser) parse() {
|
||||||
p.comp_time()
|
p.comp_time()
|
||||||
case Token.key_global:
|
case Token.key_global:
|
||||||
if !p.pref.translated && !p.pref.is_live &&
|
if !p.pref.translated && !p.pref.is_live &&
|
||||||
!p.builtin_pkg && !p.building_v {
|
!p.builtin_mod && !p.building_v {
|
||||||
p.error('__global is only allowed in translated code')
|
p.error('__global is only allowed in translated code')
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -362,18 +364,18 @@ fn (p mut Parser) import_statement() {
|
||||||
if p.peek() == .number && p.scanner.text[p.scanner.pos + 1] == `.` {
|
if p.peek() == .number && p.scanner.text[p.scanner.pos + 1] == `.` {
|
||||||
p.error('bad import format. module/submodule names cannot begin with a number.')
|
p.error('bad import format. module/submodule names cannot begin with a number.')
|
||||||
}
|
}
|
||||||
mut pkg := p.check_name().trim_space()
|
mut mod := p.check_name().trim_space()
|
||||||
mut mod_alias := pkg
|
mut mod_alias := mod
|
||||||
// submodule support
|
// submodule support
|
||||||
mut depth := 1
|
mut depth := 1
|
||||||
for p.tok == .dot {
|
for p.tok == .dot {
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
submodule := p.check_name()
|
submodule := p.check_name()
|
||||||
mod_alias = submodule
|
mod_alias = submodule
|
||||||
pkg += '.' + submodule
|
mod += '.' + submodule
|
||||||
depth++
|
depth++
|
||||||
if depth > MaxModuleDepth {
|
if depth > MaxModuleDepth {
|
||||||
p.error('module depth of $MaxModuleDepth exceeded: $pkg')
|
p.error('module depth of $MaxModuleDepth exceeded: $mod')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// aliasing (import encoding.base64 as b64)
|
// aliasing (import encoding.base64 as b64)
|
||||||
|
@ -382,16 +384,16 @@ fn (p mut Parser) import_statement() {
|
||||||
mod_alias = p.check_name()
|
mod_alias = p.check_name()
|
||||||
}
|
}
|
||||||
// add import to file scope import table
|
// add import to file scope import table
|
||||||
p.import_table.register_alias(mod_alias, pkg)
|
p.import_table.register_alias(mod_alias, mod)
|
||||||
// Make sure there are no duplicate imports
|
// Make sure there are no duplicate imports
|
||||||
if p.table.imports.contains(pkg) {
|
if p.table.imports.contains(mod) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.log('adding import $pkg')
|
p.log('adding import $mod')
|
||||||
p.table.imports << pkg
|
p.table.imports << mod
|
||||||
p.table.register_package(pkg)
|
p.table.register_module(mod)
|
||||||
|
|
||||||
p.fgenln(' ' + pkg)
|
p.fgenln(' ' + mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) const_decl() {
|
fn (p mut Parser) const_decl() {
|
||||||
|
@ -411,9 +413,9 @@ fn (p mut Parser) const_decl() {
|
||||||
//if ! (name[0] >= `A` && name[0] <= `Z`) {
|
//if ! (name[0] >= `A` && name[0] <= `Z`) {
|
||||||
//p.error('const name must be capitalized')
|
//p.error('const name must be capitalized')
|
||||||
//}
|
//}
|
||||||
// Imported consts (like GL_TRIANG.leS) dont need pkg prepended (gl__GL_TRIANG.leS)
|
// Imported consts (like GL_TRIANG.leS) dont need mod prepended (gl__GL_TRIANG.leS)
|
||||||
if !is_import {
|
if !is_import {
|
||||||
name = p.prepend_pkg(name)
|
name = p.prepend_mod(name)
|
||||||
}
|
}
|
||||||
mut typ := 'int'
|
mut typ := 'int'
|
||||||
if !is_import {
|
if !is_import {
|
||||||
|
@ -525,8 +527,8 @@ fn (p mut Parser) struct_decl() {
|
||||||
p.error('bad struct name, e.g. use `HttpRequest` instead of `HTTPRequest`')
|
p.error('bad struct name, e.g. use `HttpRequest` instead of `HTTPRequest`')
|
||||||
}
|
}
|
||||||
// Specify full type name
|
// Specify full type name
|
||||||
if !is_c && !p.builtin_pkg && p.mod != 'main' {
|
if !is_c && !p.builtin_mod && p.mod != 'main' {
|
||||||
name = p.prepend_pkg(name)
|
name = p.prepend_mod(name)
|
||||||
}
|
}
|
||||||
if p.pass == .decl && p.table.known_type(name) {
|
if p.pass == .decl && p.table.known_type(name) {
|
||||||
p.error('`$name` redeclared')
|
p.error('`$name` redeclared')
|
||||||
|
@ -682,8 +684,8 @@ fn (p mut Parser) struct_decl() {
|
||||||
fn (p mut Parser) enum_decl(_enum_name string) {
|
fn (p mut Parser) enum_decl(_enum_name string) {
|
||||||
mut enum_name := _enum_name
|
mut enum_name := _enum_name
|
||||||
// Specify full type name
|
// Specify full type name
|
||||||
if !p.builtin_pkg && p.mod != 'main' {
|
if !p.builtin_mod && p.mod != 'main' {
|
||||||
enum_name = p.prepend_pkg(enum_name)
|
enum_name = p.prepend_mod(enum_name)
|
||||||
}
|
}
|
||||||
// Skip empty enums
|
// Skip empty enums
|
||||||
if enum_name != 'int' {
|
if enum_name != 'int' {
|
||||||
|
@ -822,7 +824,7 @@ fn (p mut Parser) get_type() string {
|
||||||
if debug {
|
if debug {
|
||||||
println('\nget_type() .key_goT FN TYP line=$p.scanner.line_nr')
|
println('\nget_type() .key_goT FN TYP line=$p.scanner.line_nr')
|
||||||
}
|
}
|
||||||
mut f := Fn{name: '_', pkg: p.mod}
|
mut f := Fn{name: '_', mod: p.mod}
|
||||||
p.next()
|
p.next()
|
||||||
line_nr := p.scanner.line_nr
|
line_nr := p.scanner.line_nr
|
||||||
p.fn_args(mut f)
|
p.fn_args(mut f)
|
||||||
|
@ -883,7 +885,7 @@ fn (p mut Parser) get_type() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// map[string]int
|
// map[string]int
|
||||||
if !p.builtin_pkg && p.tok == .name && p.lit == 'map' {
|
if !p.builtin_mod && p.tok == .name && p.lit == 'map' {
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.lsbr)
|
p.check(.lsbr)
|
||||||
key_type := p.check_name()
|
key_type := p.check_name()
|
||||||
|
@ -919,19 +921,19 @@ fn (p mut Parser) get_type() string {
|
||||||
typ = p.lit
|
typ = p.lit
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Package specified? (e.g. gx.Image)
|
// Module specified? (e.g. gx.Image)
|
||||||
if p.peek() == .dot {
|
if p.peek() == .dot {
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
typ += '__$p.lit'
|
typ += '__$p.lit'
|
||||||
}
|
}
|
||||||
mut t := p.table.find_type(typ)
|
mut t := p.table.find_type(typ)
|
||||||
// "typ" not found? try "pkg__typ"
|
// "typ" not found? try "mod__typ"
|
||||||
if t.name == '' && !p.builtin_pkg {
|
if t.name == '' && !p.builtin_mod {
|
||||||
// && !p.first_pass() {
|
// && !p.first_pass() {
|
||||||
if !typ.contains('array_') && p.mod != 'main' && !typ.contains('__') &&
|
if !typ.contains('array_') && p.mod != 'main' && !typ.contains('__') &&
|
||||||
!typ.starts_with('[') {
|
!typ.starts_with('[') {
|
||||||
typ = p.prepend_pkg(typ)
|
typ = p.prepend_mod(typ)
|
||||||
}
|
}
|
||||||
t = p.table.find_type(typ)
|
t = p.table.find_type(typ)
|
||||||
if t.name == '' && !p.pref.translated && !p.first_pass() && !typ.starts_with('[') {
|
if t.name == '' && !p.pref.translated && !p.first_pass() && !typ.starts_with('[') {
|
||||||
|
@ -974,7 +976,7 @@ fn (p mut Parser) get_type() string {
|
||||||
return 'byte*'
|
return 'byte*'
|
||||||
}
|
}
|
||||||
if typ == 'voidptr' {
|
if typ == 'voidptr' {
|
||||||
//if !p.builtin_pkg && p.mod != 'os' && p.mod != 'gx' && p.mod != 'gg' && !p.pref.translated {
|
//if !p.builtin_mod && p.mod != 'os' && p.mod != 'gx' && p.mod != 'gg' && !p.pref.translated {
|
||||||
//p.error('voidptr can only be used in unsafe code')
|
//p.error('voidptr can only be used in unsafe code')
|
||||||
//}
|
//}
|
||||||
return 'void*'
|
return 'void*'
|
||||||
|
@ -1225,7 +1227,7 @@ fn (p mut Parser) assign_statement(v Var, ph int, is_map bool) {
|
||||||
//p.cgen.cur_line = left + 'opt_ok($expr)'
|
//p.cgen.cur_line = left + 'opt_ok($expr)'
|
||||||
p.cgen.resetln(left + 'opt_ok($expr, sizeof($expr_type))')
|
p.cgen.resetln(left + 'opt_ok($expr, sizeof($expr_type))')
|
||||||
}
|
}
|
||||||
else if !p.builtin_pkg && !p.check_types_no_throw(expr_type, p.assigned_type) {
|
else if !p.builtin_mod && !p.check_types_no_throw(expr_type, p.assigned_type) {
|
||||||
p.scanner.line_nr--
|
p.scanner.line_nr--
|
||||||
p.error('cannot use type `$expr_type` as type `$p.assigned_type` in assignment')
|
p.error('cannot use type `$expr_type` as type `$p.assigned_type` in assignment')
|
||||||
}
|
}
|
||||||
|
@ -1256,7 +1258,7 @@ fn (p mut Parser) var_decl() {
|
||||||
p.var_decl_name = name
|
p.var_decl_name = name
|
||||||
// Don't allow declaring a variable with the same name. Even in a child scope
|
// Don't allow declaring a variable with the same name. Even in a child scope
|
||||||
// (shadowing is not allowed)
|
// (shadowing is not allowed)
|
||||||
if !p.builtin_pkg && p.cur_fn.known_var(name) {
|
if !p.builtin_mod && p.cur_fn.known_var(name) {
|
||||||
v := p.cur_fn.find_var(name)
|
v := p.cur_fn.find_var(name)
|
||||||
p.error('redefinition of `$name`')
|
p.error('redefinition of `$name`')
|
||||||
}
|
}
|
||||||
|
@ -1395,7 +1397,7 @@ fn (p mut Parser) name_expr() string {
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
if deref {
|
if deref {
|
||||||
if p.pref.is_play && !p.builtin_pkg {
|
if p.pref.is_play && !p.builtin_mod {
|
||||||
p.error('dereferencing is temporarily disabled on the playground, will be fixed soon')
|
p.error('dereferencing is temporarily disabled on the playground, will be fixed soon')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1433,23 +1435,23 @@ fn (p mut Parser) name_expr() string {
|
||||||
// //////////////////////////
|
// //////////////////////////
|
||||||
// module ?
|
// module ?
|
||||||
// Allow shadowing (gg = gg.newcontext(); gg.draw_triangle())
|
// Allow shadowing (gg = gg.newcontext(); gg.draw_triangle())
|
||||||
if ((name == p.mod && p.table.known_pkg(name)) || p.import_table.known_alias(name))
|
if ((name == p.mod && p.table.known_mod(name)) || p.import_table.known_alias(name))
|
||||||
&& !p.cur_fn.known_var(name) && !is_c {
|
&& !p.cur_fn.known_var(name) && !is_c {
|
||||||
mut pkg := name
|
mut mod := name
|
||||||
// must be aliased module
|
// must be aliased module
|
||||||
if name != p.mod && p.import_table.known_alias(name) {
|
if name != p.mod && p.import_table.known_alias(name) {
|
||||||
// we replaced "." with "_dot_" in p.mod for C variable names, do same here.
|
// we replaced "." with "_dot_" in p.mod for C variable names, do same here.
|
||||||
pkg = p.import_table.resolve_alias(name).replace('.', '_dot_')
|
mod = p.import_table.resolve_alias(name).replace('.', '_dot_')
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
name = p.lit
|
name = p.lit
|
||||||
p.fgen(name)
|
p.fgen(name)
|
||||||
name = prepend_pkg(pkg, name)
|
name = prepend_mod(mod, name)
|
||||||
}
|
}
|
||||||
else if !p.table.known_type(name) && !p.cur_fn.known_var(name) &&
|
else if !p.table.known_type(name) && !p.cur_fn.known_var(name) &&
|
||||||
!p.table.known_fn(name) && !p.table.known_const(name) && !is_c {
|
!p.table.known_fn(name) && !p.table.known_const(name) && !is_c {
|
||||||
name = p.prepend_pkg(name)
|
name = p.prepend_mod(name)
|
||||||
}
|
}
|
||||||
// Variable
|
// Variable
|
||||||
mut v := p.cur_fn.find_var(name)
|
mut v := p.cur_fn.find_var(name)
|
||||||
|
@ -1517,7 +1519,7 @@ fn (p mut Parser) name_expr() string {
|
||||||
return enum_type.name
|
return enum_type.name
|
||||||
}
|
}
|
||||||
else if p.peek() == .lcbr {
|
else if p.peek() == .lcbr {
|
||||||
// go back to name start (pkg.name)
|
// go back to name start (mod.name)
|
||||||
/*
|
/*
|
||||||
p.scanner.pos = hack_pos
|
p.scanner.pos = hack_pos
|
||||||
p.tok = hack_tok
|
p.tok = hack_tok
|
||||||
|
@ -1582,9 +1584,9 @@ fn (p mut Parser) name_expr() string {
|
||||||
f = p.table.find_fn(name)
|
f = p.table.find_fn(name)
|
||||||
}
|
}
|
||||||
if f.name == '' {
|
if f.name == '' {
|
||||||
// If orig_name is a pkg, then printing undefined: `pkg` tells us nothing
|
// If orig_name is a mod, then printing undefined: `mod` tells us nothing
|
||||||
// if p.table.known_pkg(orig_name) {
|
// if p.table.known_mod(orig_name) {
|
||||||
if p.table.known_pkg(orig_name) || p.import_table.known_alias(orig_name) {
|
if p.table.known_mod(orig_name) || p.import_table.known_alias(orig_name) {
|
||||||
name = name.replace('__', '.').replace('_dot_', '.')
|
name = name.replace('__', '.').replace('_dot_', '.')
|
||||||
p.error('undefined: `$name`')
|
p.error('undefined: `$name`')
|
||||||
}
|
}
|
||||||
|
@ -1750,21 +1752,21 @@ fn (p mut Parser) dot(str_typ string, method_ph int) string {
|
||||||
next := p.peek()
|
next := p.peek()
|
||||||
modifying := next.is_assign() || next == .inc || next == .dec
|
modifying := next.is_assign() || next == .inc || next == .dec
|
||||||
is_vi := p.fileis('vi')
|
is_vi := p.fileis('vi')
|
||||||
if !p.builtin_pkg && !p.pref.translated && modifying && !field.is_mut && !is_vi {
|
if !p.builtin_mod && !p.pref.translated && modifying && !field.is_mut && !is_vi {
|
||||||
p.error('cannot modify immutable field `$field_name` (type `$typ.name`)')
|
p.error('cannot modify immutable field `$field_name` (type `$typ.name`)')
|
||||||
}
|
}
|
||||||
if !p.builtin_pkg && p.mod != typ.mod {
|
if !p.builtin_mod && p.mod != typ.mod {
|
||||||
}
|
}
|
||||||
// if p.pref.is_play && field.access_mod ==.private && !p.builtin_pkg && p.mod != typ.mod {
|
// if p.pref.is_play && field.access_mod ==.private && !p.builtin_mod && p.mod != typ.mod {
|
||||||
// Don't allow `arr.data`
|
// Don't allow `arr.data`
|
||||||
if field.access_mod == .private && !p.builtin_pkg && !p.pref.translated && p.mod != typ.mod {
|
if field.access_mod == .private && !p.builtin_mod && !p.pref.translated && p.mod != typ.mod {
|
||||||
// println('$typ.name :: $field.name ')
|
// println('$typ.name :: $field.name ')
|
||||||
// println(field.access_mod)
|
// println(field.access_mod)
|
||||||
p.error('cannot refer to unexported field `$field_name` (type `$typ.name`)')
|
p.error('cannot refer to unexported field `$field_name` (type `$typ.name`)')
|
||||||
}
|
}
|
||||||
// if field.access_mod ==.public && p.peek() == .assign && !p.builtin_pkg && p.mod != typ.mod {
|
// if field.access_mod ==.public && p.peek() == .assign && !p.builtin_mod && p.mod != typ.mod {
|
||||||
// Don't allow `str.len = 0`
|
// Don't allow `str.len = 0`
|
||||||
if field.access_mod == .public && !p.builtin_pkg && p.mod != typ.mod {
|
if field.access_mod == .public && !p.builtin_mod && p.mod != typ.mod {
|
||||||
if !field.is_mut && !p.pref.translated && modifying {
|
if !field.is_mut && !p.pref.translated && modifying {
|
||||||
p.error('cannot modify public immutable field `$field_name` (type `$typ.name`)')
|
p.error('cannot modify public immutable field `$field_name` (type `$typ.name`)')
|
||||||
}
|
}
|
||||||
|
@ -1815,8 +1817,8 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
||||||
if is_str {
|
if is_str {
|
||||||
typ = 'byte'
|
typ = 'byte'
|
||||||
p.fgen('[')
|
p.fgen('[')
|
||||||
// Direct faster access to .str[i] in builtin package
|
// Direct faster access to .str[i] in builtin modules
|
||||||
if p.builtin_pkg {
|
if p.builtin_mod {
|
||||||
p.gen('.str[')
|
p.gen('.str[')
|
||||||
close_bracket = true
|
close_bracket = true
|
||||||
}
|
}
|
||||||
|
@ -1866,7 +1868,7 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
||||||
typ = 'void*'
|
typ = 'void*'
|
||||||
}
|
}
|
||||||
// No bounds check in translated from C code
|
// No bounds check in translated from C code
|
||||||
if p.pref.translated && !p.builtin_pkg{
|
if p.pref.translated && !p.builtin_mod{
|
||||||
// Cast void* to typ*: add (typ*) to the beginning of the assignment :
|
// Cast void* to typ*: add (typ*) to the beginning of the assignment :
|
||||||
// ((int*)a.data = ...
|
// ((int*)a.data = ...
|
||||||
p.cgen.set_placeholder(fn_ph, '(($typ*)(')
|
p.cgen.set_placeholder(fn_ph, '(($typ*)(')
|
||||||
|
@ -1898,7 +1900,7 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
||||||
p.expression()
|
p.expression()
|
||||||
}
|
}
|
||||||
p.check(.rsbr)
|
p.check(.rsbr)
|
||||||
// if (is_str && p.builtin_pkg) || is_ptr || is_fixed_arr && ! (is_ptr && is_arr) {
|
// if (is_str && p.builtin_mod) || is_ptr || is_fixed_arr && ! (is_ptr && is_arr) {
|
||||||
if close_bracket {
|
if close_bracket {
|
||||||
p.gen(']/*r$typ $v.is_mut*/')
|
p.gen(']/*r$typ $v.is_mut*/')
|
||||||
}
|
}
|
||||||
|
@ -1910,7 +1912,7 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
||||||
p.tok == .mult_assign || p.tok == .div_assign || p.tok == .xor_assign || p.tok == .mod_assign ||
|
p.tok == .mult_assign || p.tok == .div_assign || p.tok == .xor_assign || p.tok == .mod_assign ||
|
||||||
p.tok == .or_assign || p.tok == .and_assign || p.tok == .righ_shift_assign ||
|
p.tok == .or_assign || p.tok == .and_assign || p.tok == .righ_shift_assign ||
|
||||||
p.tok == .left_shift_assign {
|
p.tok == .left_shift_assign {
|
||||||
if is_indexer && is_str && !p.builtin_pkg {
|
if is_indexer && is_str && !p.builtin_mod {
|
||||||
p.error('strings are immutable')
|
p.error('strings are immutable')
|
||||||
}
|
}
|
||||||
assign_pos := p.cgen.cur_line.len
|
assign_pos := p.cgen.cur_line.len
|
||||||
|
@ -1948,7 +1950,7 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
||||||
// p.error('didnt assign')
|
// p.error('didnt assign')
|
||||||
// }
|
// }
|
||||||
// m[key]. no =, just a getter
|
// m[key]. no =, just a getter
|
||||||
else if (is_map || is_arr || (is_str && !p.builtin_pkg)) && is_indexer {
|
else if (is_map || is_arr || (is_str && !p.builtin_mod)) && is_indexer {
|
||||||
// Erase var name we generated earlier: "int a = m, 0"
|
// Erase var name we generated earlier: "int a = m, 0"
|
||||||
// "m, 0" gets killed since we need to start from scratch. It's messy.
|
// "m, 0" gets killed since we need to start from scratch. It's messy.
|
||||||
// "m, 0" is an index expression, save it before deleting and insert later in map_get()
|
// "m, 0" is an index expression, save it before deleting and insert later in map_get()
|
||||||
|
@ -1966,7 +1968,7 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
||||||
p.cgen.insert_before('$typ $tmp = $def; bool $tmp_ok = map_get($index_expr, & $tmp);')
|
p.cgen.insert_before('$typ $tmp = $def; bool $tmp_ok = map_get($index_expr, & $tmp);')
|
||||||
}
|
}
|
||||||
else if is_arr {
|
else if is_arr {
|
||||||
if p.pref.translated && !p.builtin_pkg {
|
if p.pref.translated && !p.builtin_mod {
|
||||||
p.gen('$index_expr ]')
|
p.gen('$index_expr ]')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1977,7 +1979,7 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if is_str && !p.builtin_pkg {
|
else if is_str && !p.builtin_mod {
|
||||||
p.gen('string_at($index_expr)')
|
p.gen('string_at($index_expr)')
|
||||||
}
|
}
|
||||||
// Zero the string after map_get() if it's nil, numbers are automatically 0
|
// Zero the string after map_get() if it's nil, numbers are automatically 0
|
||||||
|
@ -2536,7 +2538,7 @@ fn (p mut Parser) array_init() string {
|
||||||
// fixed length arrays with a const len: `nums := [N]int`, same as `[10]int` basically
|
// fixed length arrays with a const len: `nums := [N]int`, same as `[10]int` basically
|
||||||
mut is_const_len := false
|
mut is_const_len := false
|
||||||
if p.tok == .name {
|
if p.tok == .name {
|
||||||
c := p.table.find_const(p.prepend_pkg(p.lit))
|
c := p.table.find_const(p.prepend_mod(p.lit))
|
||||||
if c.name != '' && c.typ == 'int' && p.peek() == .rsbr && !p.inside_const {
|
if c.name != '' && c.typ == 'int' && p.peek() == .rsbr && !p.inside_const {
|
||||||
is_integer = true
|
is_integer = true
|
||||||
is_const_len = true
|
is_const_len = true
|
||||||
|
@ -2733,7 +2735,7 @@ fn (p mut Parser) struct_init(typ string, is_c_struct_init bool) string {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
field_typ := field.typ
|
field_typ := field.typ
|
||||||
if !p.builtin_pkg && field_typ.ends_with('*') && field_typ.contains('Cfg') {
|
if !p.builtin_mod && field_typ.ends_with('*') && field_typ.contains('Cfg') {
|
||||||
p.error('pointer field `${typ}.${field.name}` must be initialized')
|
p.error('pointer field `${typ}.${field.name}` must be initialized')
|
||||||
}
|
}
|
||||||
def_val := type_default(field_typ)
|
def_val := type_default(field_typ)
|
||||||
|
@ -3255,12 +3257,12 @@ fn (p mut Parser) return_st() {
|
||||||
p.returns = true
|
p.returns = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepend_pkg(pkg, name string) string {
|
fn prepend_mod(mod, name string) string {
|
||||||
return '${pkg}__${name}'
|
return '${mod}__${name}'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p &Parser) prepend_pkg(name string) string {
|
fn (p &Parser) prepend_mod(name string) string {
|
||||||
return prepend_pkg(p.mod, name)
|
return prepend_mod(p.mod, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) go_statement() {
|
fn (p mut Parser) go_statement() {
|
||||||
|
|
|
@ -9,16 +9,17 @@ import strings
|
||||||
|
|
||||||
struct Table {
|
struct Table {
|
||||||
mut:
|
mut:
|
||||||
types []Type
|
types []Type
|
||||||
consts []Var
|
consts []Var
|
||||||
fns map[string]Fn
|
fns map[string]Fn
|
||||||
generic_fns []GenTable //map[string]GenTable // generic_fns['listen_and_serve'] == ['Blog', 'Forum']
|
generic_fns []GenTable //map[string]GenTable // generic_fns['listen_and_serve'] == ['Blog', 'Forum']
|
||||||
obf_ids map[string]int // obf_ids['myfunction'] == 23
|
obf_ids map[string]int // obf_ids['myfunction'] == 23
|
||||||
packages []string // List of all modules registered by the application
|
modules []string // List of all modules registered by the application
|
||||||
imports []string // List of all imports
|
imports []string // List of all imports
|
||||||
flags []string // ['-framework Cocoa', '-lglfw3']
|
file_imports []FileImportTable // List of imports for file
|
||||||
fn_cnt int atomic
|
flags []string // ['-framework Cocoa', '-lglfw3']
|
||||||
obfuscate bool
|
fn_cnt int atomic
|
||||||
|
obfuscate bool
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GenTable {
|
struct GenTable {
|
||||||
|
@ -140,6 +141,7 @@ fn new_table(obfuscate bool) *Table {
|
||||||
//generic_fns: map[string]GenTable{}
|
//generic_fns: map[string]GenTable{}
|
||||||
generic_fns: []GenTable
|
generic_fns: []GenTable
|
||||||
obfuscate: obfuscate
|
obfuscate: obfuscate
|
||||||
|
file_imports: []FileImportTable
|
||||||
}
|
}
|
||||||
t.register_type('int')
|
t.register_type('int')
|
||||||
t.register_type('size_t')
|
t.register_type('size_t')
|
||||||
|
@ -181,11 +183,11 @@ fn (t mut Table) var_cgen_name(name string) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (t mut Table) register_package(pkg string) {
|
fn (t mut Table) register_module(mod string) {
|
||||||
if t.packages.contains(pkg) {
|
if t.modules.contains(mod) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.packages << pkg
|
t.modules << mod
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) register_array(typ string) {
|
fn (p mut Parser) register_array(typ string) {
|
||||||
|
@ -210,8 +212,8 @@ fn (p mut Parser) register_map(typ string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (table &Table) known_pkg(pkg string) bool {
|
fn (table &Table) known_mod(mod string) bool {
|
||||||
return pkg in table.packages
|
return mod in table.modules
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (t mut Table) register_const(name, typ, mod string, is_imported bool) {
|
fn (t mut Table) register_const(name, typ, mod string, is_imported bool) {
|
||||||
|
@ -308,9 +310,9 @@ fn (t mut Table) register_type_with_parent(typ, parent string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
mut pkg := ''
|
mut mod := ''
|
||||||
if parent == 'array' {
|
if parent == 'array' {
|
||||||
pkg = 'builtin'
|
mod = 'builtin'
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
t.types << Type {
|
t.types << Type {
|
||||||
|
@ -433,7 +435,7 @@ fn (t mut Type) add_gen_type(type_name string) {
|
||||||
fn (p &Parser) find_type(name string) *Type {
|
fn (p &Parser) find_type(name string) *Type {
|
||||||
typ := p.table.find_type(name)
|
typ := p.table.find_type(name)
|
||||||
if typ.name.len == 0 {
|
if typ.name.len == 0 {
|
||||||
return p.table.find_type(p.prepend_pkg(name))
|
return p.table.find_type(p.prepend_mod(name))
|
||||||
}
|
}
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
@ -481,7 +483,7 @@ fn (p mut Parser) _check_types(got, expected string, throw bool) bool {
|
||||||
}
|
}
|
||||||
// Todo void* allows everything right now
|
// Todo void* allows everything right now
|
||||||
if got=='void*' || expected=='void*' {
|
if got=='void*' || expected=='void*' {
|
||||||
// if !p.builtin_pkg {
|
// if !p.builtin_mod {
|
||||||
if p.pref.is_play {
|
if p.pref.is_play {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -655,14 +657,14 @@ fn (table mut Table) cgen_name(f &Fn) string {
|
||||||
// Avoid name conflicts (with things like abs(), print() etc).
|
// Avoid name conflicts (with things like abs(), print() etc).
|
||||||
// Generate b_abs(), b_print()
|
// Generate b_abs(), b_print()
|
||||||
// TODO duplicate functionality
|
// TODO duplicate functionality
|
||||||
if f.pkg == 'builtin' && CReserved.contains(f.name) {
|
if f.mod == 'builtin' && CReserved.contains(f.name) {
|
||||||
return 'v_$name'
|
return 'v_$name'
|
||||||
}
|
}
|
||||||
// Obfuscate but skip certain names
|
// Obfuscate but skip certain names
|
||||||
// TODO ugly, fix
|
// TODO ugly, fix
|
||||||
if table.obfuscate && f.name != 'main' && f.name != 'WinMain' && f.pkg != 'builtin' && !f.is_c &&
|
if table.obfuscate && f.name != 'main' && f.name != 'WinMain' && f.mod != 'builtin' && !f.is_c &&
|
||||||
f.pkg != 'darwin' && f.pkg != 'os' && !f.name.contains('window_proc') && f.name != 'gg__vec2' &&
|
f.mod != 'darwin' && f.mod != 'os' && !f.name.contains('window_proc') && f.name != 'gg__vec2' &&
|
||||||
f.name != 'build_token_str' && f.name != 'build_keys' && f.pkg != 'json' &&
|
f.name != 'build_token_str' && f.name != 'build_keys' && f.mod != 'json' &&
|
||||||
!name.ends_with('_str') && !name.contains('contains') {
|
!name.ends_with('_str') && !name.contains('contains') {
|
||||||
mut idx := table.obf_ids[name]
|
mut idx := table.obf_ids[name]
|
||||||
// No such function yet, register it
|
// No such function yet, register it
|
||||||
|
|
Loading…
Reference in New Issue