compiler: rework flags & support win path spaces + more
							parent
							
								
									e8068b5e1d
								
							
						
					
					
						commit
						8ac0a2b2dd
					
				|  | @ -10,6 +10,9 @@ import ( | |||
| ) | ||||
| 
 | ||||
| fn (v mut V) cc() { | ||||
| 	// build any thirdparty obj files
 | ||||
| 	v.build_thirdparty_obj_files() | ||||
| 
 | ||||
| 	// Just create a c file and exit
 | ||||
| 	if v.out_name.ends_with('.c') { | ||||
| 		os.mv(v.out_name_c, v.out_name) | ||||
|  | @ -33,15 +36,6 @@ fn (v mut V) cc() { | |||
| 	v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name') | ||||
| 	mut a := [v.pref.cflags, '-std=gnu11', '-w'] // arguments for the C compiler
 | ||||
| 
 | ||||
| 	mut seenflags := map[string]int | ||||
| 	mut uniqueflags := []string | ||||
| 	for f in v.table.flags { | ||||
| 		seenflags[ f ] = seenflags[ f ] + 1 | ||||
| 		if seenflags[ f ] > 1 { continue } | ||||
| 		uniqueflags << f | ||||
| 	} | ||||
| 	flags := uniqueflags.join(' ') | ||||
| 	// Set out name
 | ||||
| 	if v.pref.is_so { | ||||
| 		a << '-shared -fPIC '// -Wl,-z,defs'
 | ||||
| 		v.out_name = v.out_name + '.so' | ||||
|  | @ -92,7 +86,7 @@ fn (v mut V) cc() { | |||
| 	// -I flags
 | ||||
| 	/* | ||||
| mut args := '' | ||||
| 	for flag in v.table.flags { | ||||
| 	for flag in v.get_os_cflags() { | ||||
| 		if !flag.starts_with('-l') { | ||||
| 			args += flag | ||||
| 			args += ' ' | ||||
|  | @ -133,7 +127,9 @@ mut args := '' | |||
| 	if v.os == .mac { | ||||
| 		a << '-mmacosx-version-min=10.7' | ||||
| 	} | ||||
| 	a << flags | ||||
| 	for flag in v.get_os_cflags() { | ||||
| 		a << flag.format() | ||||
| 	} | ||||
| 	a << libs | ||||
| 	// macOS code can include objective C  TODO remove once objective C is replaced with C
 | ||||
| 	// Without these libs compilation will fail on Linux
 | ||||
|  | @ -224,9 +220,9 @@ fn (c mut V) cc_windows_cross() { | |||
| 	} | ||||
| 	mut args := '-o $c.out_name -w -L. ' | ||||
| 	// -I flags
 | ||||
| 	for flag in c.table.flags { | ||||
| 		if !flag.starts_with('-l') { | ||||
| 				args += flag | ||||
| 	for flag in c.get_os_cflags() { | ||||
| 		if flag.name != '-l' { | ||||
| 				args += flag.format() | ||||
| 				args += ' ' | ||||
| 		} | ||||
| 	} | ||||
|  | @ -243,9 +239,9 @@ fn (c mut V) cc_windows_cross() { | |||
| 	} | ||||
| 	args += ' $c.out_name_c ' | ||||
| 	// -l flags (libs)
 | ||||
| 	for flag in c.table.flags { | ||||
| 			if flag.starts_with('-l') { | ||||
| 					args += flag | ||||
| 	for flag in c.get_os_cflags() { | ||||
| 			if flag.name == '-l' { | ||||
| 					args += flag.format() | ||||
| 					args += ' ' | ||||
| 			} | ||||
| 	} | ||||
|  | @ -289,6 +285,19 @@ fn (c mut V) cc_windows_cross() { | |||
| 	println('Done!') | ||||
| } | ||||
| 
 | ||||
| fn (c V) build_thirdparty_obj_files() { | ||||
| 	for flag in c.get_os_cflags() { | ||||
| 		if flag.value.ends_with('.o') { | ||||
| 			if c.os == .msvc { | ||||
| 				build_thirdparty_obj_file_with_msvc(flag.value) | ||||
| 			} | ||||
| 			else { | ||||
| 				build_thirdparty_obj_file(flag.value) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn find_c_compiler() string { | ||||
| 	args := env_vflags_and_os_args().join(' ') | ||||
| 	defaultcc := find_c_compiler_default() | ||||
|  | @ -306,10 +315,6 @@ fn find_c_compiler_default() string { | |||
| } | ||||
| 
 | ||||
| fn find_c_compiler_thirdparty_options() string { | ||||
| 	$if windows {	return '' } | ||||
| 	$if windows { return '' } | ||||
| 	return '-fPIC' | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,115 @@ | |||
| // Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
 | ||||
| // Use of this source code is governed by an MIT license
 | ||||
| // that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| module main | ||||
| 
 | ||||
| import os | ||||
| 
 | ||||
| // C flag
 | ||||
| struct CFlag{ | ||||
| 	os    string // eg. windows | darwin | linux
 | ||||
| 	name  string // eg. -I
 | ||||
| 	value string // eg. /path/to/incude
 | ||||
| } | ||||
| 
 | ||||
| // check if cflag is in table
 | ||||
| fn (table &Table) has_cflag(cflag CFlag) bool { | ||||
| 	for cf in table.cflags { | ||||
| 		if cf.os == cflag.os && cf.name == cflag.name && cf.value == cflag.value { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // get flags for current os
 | ||||
| fn (v V) get_os_cflags() []CFlag { | ||||
| 	mut flags := []CFlag | ||||
| 	for flag in v.table.cflags { | ||||
| 		if flag.os == '' | ||||
| 		|| (flag.os == 'linux' && v.os == .linux) | ||||
| 		|| (flag.os == 'darwin' && v.os == .mac) | ||||
| 		|| (flag.os == 'windows' && (v.os == .windows || v.os == .msvc)) { | ||||
| 			flags << flag | ||||
| 		} | ||||
| 	} | ||||
| 	return flags | ||||
| } | ||||
| 
 | ||||
| // format flag
 | ||||
| fn (cf &CFlag) format() string { | ||||
| 	mut value := cf.value | ||||
| 	// convert to absolute path
 | ||||
| 	if cf.name == '-I' || cf.name == '-L' || value.ends_with('.o') { | ||||
| 		value = '"'+os.realpath(value)+'"' | ||||
| 	} | ||||
| 	return '$cf.name $value'.trim_space() | ||||
| } | ||||
| 
 | ||||
| // parse the flags to []CFlag
 | ||||
| // Note: clean up big time (joe-c)
 | ||||
| fn (table mut Table) parse_cflag(cflag string) { | ||||
| 	allowed_flags := [ | ||||
| 		'framework', | ||||
| 		'library', | ||||
| 		'I', 'l', 'L',  | ||||
| 	] | ||||
| 	mut flag := cflag.trim_space() | ||||
| 	if flag == '' { | ||||
| 		return | ||||
| 	} | ||||
| 	mut fos := '' | ||||
| 	mut name := '' | ||||
| 	if flag.starts_with('linux') || flag.starts_with('darwin') || flag.starts_with('windows') { | ||||
| 		pos := flag.index(' ') | ||||
| 		fos = flag.left(pos).trim_space() | ||||
| 		flag = flag.right(pos).trim_space() | ||||
| 	} | ||||
| 	for { | ||||
| 		mut index := -1 | ||||
| 		mut value := '' | ||||
| 		if flag[0] == `-` { | ||||
| 			for f in allowed_flags { | ||||
| 				i := 1+f.len | ||||
| 				if i < flag.len && f == flag.substr(1,i) { | ||||
| 					name = flag.left(i).trim_space() | ||||
| 					flag = flag.right(i).trim_space() | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		for i in [flag.index(' '), flag.index(',')] { | ||||
| 			if index == -1 || (i != -1 && i < index) { | ||||
| 				index = i | ||||
| 			} | ||||
| 		} if index != -1 && flag[index] == ` ` && flag[index+1] == `-` { | ||||
| 			for f in allowed_flags { | ||||
| 				i := index+f.len | ||||
| 				if i < flag.len && f == flag.substr(index, i) { | ||||
| 					index = i | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			value = flag.left(index).trim_space() | ||||
| 			flag = flag.right(index).trim_space() | ||||
| 		} else if index != -1 && index < flag.len-2 && flag[index] == `,` { | ||||
| 			value = flag.left(index).trim_space() | ||||
| 			flag = flag.right(index+1).trim_space() | ||||
| 		} else { | ||||
| 			value = flag.trim_space() | ||||
| 			index = -1 | ||||
| 		} | ||||
| 		cf := CFlag{ | ||||
| 			os:    fos, | ||||
| 			name:  name, | ||||
| 			value: value | ||||
| 		} | ||||
| 		if !table.has_cflag(cf) { | ||||
| 			table.cflags << cf | ||||
| 		} | ||||
| 		if index == -1 { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -240,13 +240,13 @@ fn (g mut CGen) add_to_main(s string) { | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| fn build_thirdparty_obj_file(flag string) { | ||||
| 	obj_path := flag.all_after(' ') | ||||
| fn build_thirdparty_obj_file(path string) { | ||||
| 	obj_path := os.realpath(path) | ||||
| 	if os.file_exists(obj_path) { | ||||
| 		return | ||||
| 	} | ||||
| 	println('$obj_path not found, building it...') | ||||
| 	parent := os.dir( obj_path ) | ||||
| 	parent := os.dir(obj_path) | ||||
| 	files := os.ls(parent) | ||||
| 	mut cfiles := '' | ||||
| 	for file in files { | ||||
|  | @ -281,15 +281,15 @@ fn os_name_to_ifdef(name string) string { | |||
| } | ||||
| 
 | ||||
| fn platform_postfix_to_ifdefguard(name string) string { | ||||
|   switch name { | ||||
|     case '.v': return '' // no guard needed
 | ||||
|     case '_win.v': return '#ifdef _WIN32' | ||||
|     case '_nix.v': return '#ifndef _WIN32' | ||||
|     case '_lin.v': return '#ifdef __linux__' | ||||
|     case '_mac.v': return '#ifdef __APPLE__' | ||||
|   } | ||||
|   cerror('bad platform_postfix "$name"') | ||||
|   return '' | ||||
| 	switch name { | ||||
| 		case '.v': return '' // no guard needed
 | ||||
| 		case '_win.v': return '#ifdef _WIN32' | ||||
| 		case '_nix.v': return '#ifndef _WIN32' | ||||
| 		case '_lin.v': return '#ifdef __linux__' | ||||
| 		case '_mac.v': return '#ifdef __APPLE__' | ||||
| 	} | ||||
| 	cerror('bad platform_postfix "$name"') | ||||
| 	return '' | ||||
| } | ||||
| 
 | ||||
| // C struct definitions, ordered
 | ||||
|  | @ -383,4 +383,3 @@ fn sort_structs(types []Type) []Type { | |||
| 	} | ||||
| 	return types_sorted | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -141,46 +141,11 @@ fn (p mut Parser) chash() { | |||
| 	is_sig := p.is_sig() | ||||
| 	if hash.starts_with('flag ') { | ||||
| 		mut flag := hash.right(5) | ||||
| 		// No the right os? Skip!
 | ||||
| 		// mut ok := true
 | ||||
| 		if hash.contains('linux') && p.os != .linux { | ||||
| 			return | ||||
| 		} | ||||
| 		else if hash.contains('darwin') && p.os != .mac { | ||||
| 			return | ||||
| 		} | ||||
| 		else if hash.contains('windows') && (p.os != .windows && p.os != .msvc) { | ||||
| 			return | ||||
| 		} | ||||
| 		// Remove "linux" etc from flag
 | ||||
| 		if flag.contains('linux') || flag.contains('darwin') || flag.contains('windows') { | ||||
| 			pos := flag.index(' ') | ||||
| 			flag = flag.right(pos) | ||||
| 		} | ||||
| 		has_vroot := flag.contains('@VROOT') | ||||
| 		flag = flag.trim_space().replace('@VROOT', p.vroot) | ||||
| 		if p.table.flags.contains(flag) { | ||||
| 			return | ||||
| 		} | ||||
| 		// expand `@VMOD/pg/pg.o` to absolute path
 | ||||
| 		has_vmod := flag.contains('@VMOD') | ||||
| 		flag = flag.trim_space().replace('@VMOD', ModPath) | ||||
| 		if p.table.flags.contains(flag) { | ||||
| 			return | ||||
| 		} | ||||
| 		// expand `@VROOT` `@VMOD` to absolute path
 | ||||
| 		flag = flag.replace('@VROOT', p.vroot) | ||||
| 		flag = flag.replace('@VMOD', ModPath) | ||||
| 		p.log('adding flag "$flag"') | ||||
| 		// `@VROOT/thirdparty/glad/glad.o`, make sure it exists, otherwise build it
 | ||||
| 		if (has_vroot || has_vmod) && flag.contains('.o') { | ||||
| 			flag = os.realpath( flag ) | ||||
| 			//println( 'absolute filepath to objectfile is now: $flag | os is: $p.os ')
 | ||||
| 			if p.os == .msvc { | ||||
| 				build_thirdparty_obj_file_with_msvc(flag) | ||||
| 			} | ||||
| 			else { | ||||
| 				build_thirdparty_obj_file(flag) | ||||
| 			} | ||||
| 		} | ||||
| 		p.table.flags << flag | ||||
| 		p.table.parse_cflag(flag) | ||||
| 		return | ||||
| 	} | ||||
| 	if hash.starts_with('include') { | ||||
|  |  | |||
|  | @ -325,7 +325,9 @@ fn (v mut V) compile() { | |||
|   cgen.save() | ||||
| 	if v.pref.is_verbose { | ||||
| 		v.log('flags=') | ||||
| 		println(v.table.flags) | ||||
| 		for flag in v.get_os_cflags() { | ||||
| 			println(' * ' + flag.format()) | ||||
| 		} | ||||
| 	} | ||||
| 	v.cc() | ||||
| } | ||||
|  | @ -437,7 +439,7 @@ fn (v V) run_compiled_executable_and_exit() { | |||
| 	if v.pref.is_verbose { | ||||
| 		println('============ running $v.out_name ============') | ||||
| 	}	 | ||||
| 	mut cmd := final_target_out_name(v.out_name).replace('.exe','') | ||||
| 	mut cmd := '"' + final_target_out_name(v.out_name).replace('.exe','') + '"' | ||||
| 	if os.args.len > 3 { | ||||
| 		cmd += ' ' + os.args.right(3).join(' ') | ||||
| 	} | ||||
|  | @ -781,9 +783,7 @@ fn new_v(args[]string) &V { | |||
| 	vroot := os.dir(os.executable()) | ||||
| 	//println('VROOT=$vroot')
 | ||||
| 	// v.exe's parent directory should contain vlib
 | ||||
| 	if os.dir_exists(vroot) && os.dir_exists(vroot + '/vlib/builtin') { | ||||
| 
 | ||||
| 	}  else { | ||||
| 	if !os.dir_exists(vroot) || !os.dir_exists(vroot + '/vlib/builtin') { | ||||
| 		println('vlib not found. It should be next to the V executable. ') | ||||
| 		println('Go to https://vlang.io to install V.') | ||||
| 		exit(1) | ||||
|  |  | |||
							
								
								
									
										137
									
								
								compiler/msvc.v
								
								
								
								
							
							
						
						
									
										137
									
								
								compiler/msvc.v
								
								
								
								
							|  | @ -207,11 +207,6 @@ fn find_msvc() ?MsvcResult { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct ParsedFlag { | ||||
| 	f string | ||||
| 	arg string | ||||
| } | ||||
| 
 | ||||
| pub fn (v mut V) cc_msvc() {  | ||||
| 	r := find_msvc() or { | ||||
| 		// TODO: code reuse
 | ||||
|  | @ -305,99 +300,41 @@ pub fn (v mut V) cc_msvc() { | |||
| 	mut lib_paths := []string{} | ||||
| 	mut other_flags := []string{} | ||||
| 
 | ||||
| 	// Emily:
 | ||||
| 	// this is a hack to try and support -l -L and object files
 | ||||
| 	// passed on the command line
 | ||||
| 	mut seenflags := map[string]int // no need to add the same flags more than once
 | ||||
| 	for f in v.table.flags { | ||||
| 		seenflags[ f ] = seenflags[ f ] + 1 | ||||
| 		if seenflags[ f ] > 1 { continue } | ||||
| 		// People like to put multiple flags per line (which really complicates things)
 | ||||
| 		// ...so we need to handle that
 | ||||
| 		mut rest := f | ||||
| 	for flag in v.get_os_cflags() { | ||||
| 		mut arg := flag.value | ||||
| 		//println('fl: $flag.name | flag arg: $arg')
 | ||||
| 
 | ||||
| 		mut flags := []ParsedFlag{} | ||||
| 		for { | ||||
| 			mut base := rest | ||||
| 
 | ||||
| 			fl := if rest.starts_with('-') { | ||||
| 				base = rest.right(2).trim_space() | ||||
| 				rest.left(2) | ||||
| 			} else { | ||||
| 				'' | ||||
| 			} | ||||
| 
 | ||||
| 			// Which ever one of these is lowest we use
 | ||||
| 			// TODO: we really shouldnt support all of these cmon
 | ||||
| 			mut lowest := base.index('-') | ||||
| 			// dont break paths with hyphens
 | ||||
| 			if lowest != 0  { | ||||
| 				lowest = -1 | ||||
| 			} | ||||
| 			for x in [base.index(' '), base.index(',')] { | ||||
| 				if (x < lowest && x != -1) || lowest == -1 { | ||||
| 					lowest = x | ||||
| 				} | ||||
| 			} | ||||
| 			arg := if lowest != -1 { | ||||
| 				rest = base.right(lowest).trim_space().trim(',') | ||||
| 				base.left(lowest).trim_space().trim(',') | ||||
| 			} else { | ||||
| 				rest = '' | ||||
| 				base.trim_space() | ||||
| 			} | ||||
| 
 | ||||
| 			flags << ParsedFlag { | ||||
| 				fl, arg | ||||
| 			} | ||||
| 
 | ||||
| 			if rest.len == 0 { | ||||
| 				break | ||||
| 		// We need to see if the flag contains -l
 | ||||
| 		// -l isnt recognised and these libs will be passed straight to the linker
 | ||||
| 		// by the compiler
 | ||||
| 		if flag.name == '-l' { | ||||
| 			if arg.ends_with('.dll') { | ||||
| 				cerror('MSVC cannot link against a dll (`#flag -l $arg`)') | ||||
| 			} | ||||
| 			// MSVC has no method of linking against a .dll
 | ||||
| 			// TODO: we should look for .defs aswell
 | ||||
| 			lib_lib := arg + '.lib' | ||||
| 			real_libs << lib_lib | ||||
| 		} | ||||
| 
 | ||||
| 		for flag in flags { | ||||
| 			fl := flag.f | ||||
| 			mut arg := flag.arg | ||||
| 			if fl == '-I' || fl == '-L' { | ||||
| 				arg = os.realpath( arg ) | ||||
| 			} | ||||
| 			//println('fl: $fl | flag arg: $arg')
 | ||||
| 
 | ||||
| 			// We need to see if the flag contains -l
 | ||||
| 			// -l isnt recognised and these libs will be passed straight to the linker
 | ||||
| 			// by the compiler
 | ||||
| 			if fl == '-l' { | ||||
| 				if arg.ends_with('.dll') { | ||||
| 					cerror('MSVC cannot link against a dll (`#flag -l $arg`)') | ||||
| 				} | ||||
| 				// MSVC has no method of linking against a .dll
 | ||||
| 				// TODO: we should look for .defs aswell
 | ||||
| 				lib_lib := arg + '.lib' | ||||
| 				real_libs << lib_lib | ||||
| 			} | ||||
| 			else if fl == '-I' { | ||||
| 				inc_paths << ' -I "$arg" ' | ||||
| 			} | ||||
| 			else if fl == '-L' { | ||||
| 				lpath := f.right(2).trim_space() | ||||
| 				lib_paths << lpath | ||||
| 				lib_paths << lpath + os.PathSeparator + 'msvc' | ||||
| 				// The above allows putting msvc specific .lib files in a subfolder msvc/ ,
 | ||||
| 				// where gcc will NOT find them, but cl will do...
 | ||||
| 				// NB: gcc is smart enough to not need .lib files at all in most cases, the .dll is enough.
 | ||||
| 				// When both a msvc .lib file and .dll file are present in the same folder,
 | ||||
| 				// as for example for glfw3, compilation with gcc would fail.
 | ||||
| 			} | ||||
| 			else if arg.ends_with('.o') { | ||||
| 				// msvc expects .obj not .o
 | ||||
| 				other_flags << arg + 'bj' | ||||
| 			}  | ||||
| 			else { | ||||
| 				other_flags << arg | ||||
| 			} | ||||
| 		else if flag.name == '-I' { | ||||
| 			inc_paths << ' ' + flag.format() + ' ' | ||||
| 		} | ||||
| 		else if flag.name == '-L' { | ||||
| 			lpath := flag.value | ||||
| 			lib_paths << '"' + lpath + '"' | ||||
| 			lib_paths << '"' + lpath + os.PathSeparator + 'msvc' + '"' | ||||
| 			// The above allows putting msvc specific .lib files in a subfolder msvc/ ,
 | ||||
| 			// where gcc will NOT find them, but cl will do...
 | ||||
| 			// NB: gcc is smart enough to not need .lib files at all in most cases, the .dll is enough.
 | ||||
| 			// When both a msvc .lib file and .dll file are present in the same folder,
 | ||||
| 			// as for example for glfw3, compilation with gcc would fail.
 | ||||
| 		} | ||||
| 		else if flag.value.ends_with('.o') { | ||||
| 			other_flags << flag.format().replace('.o', '.obj') | ||||
| 		} | ||||
| 		else { | ||||
| 			other_flags << arg | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
| 
 | ||||
| 	// Include the base paths
 | ||||
|  | @ -463,18 +400,16 @@ pub fn (v mut V) cc_msvc() { | |||
| 	os.rm(out_name_obj) | ||||
| } | ||||
| 
 | ||||
| fn build_thirdparty_obj_file_with_msvc(flag string) { | ||||
| fn build_thirdparty_obj_file_with_msvc(path string) { | ||||
| 	msvc := find_msvc() or { | ||||
| 		println('Could not find visual studio') | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	mut obj_path := flag.all_after(' ') | ||||
| 	// msvc expects .obj not .o
 | ||||
| 	mut obj_path := '${path}bj' | ||||
| 
 | ||||
| 	if obj_path.ends_with('.o') { | ||||
| 		// msvc expects .obj not .o
 | ||||
| 		obj_path = obj_path + 'bj' | ||||
| 	} | ||||
| 	obj_path = os.realpath(obj_path) | ||||
| 
 | ||||
| 	if os.file_exists(obj_path) { | ||||
| 		println('$obj_path already build.') | ||||
|  | @ -482,7 +417,7 @@ fn build_thirdparty_obj_file_with_msvc(flag string) { | |||
| 	}  | ||||
| 
 | ||||
| 	println('$obj_path not found, building it (with msvc)...')  | ||||
| 	parent := os.dir( obj_path ) | ||||
| 	parent := os.dir(obj_path) | ||||
| 	files := os.ls(parent) | ||||
| 
 | ||||
| 	mut cfiles := ''  | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ mut: | |||
| 	modules      []string // List of all modules registered by the application
 | ||||
| 	imports      []string // List of all imports
 | ||||
| 	file_imports []FileImportTable // List of imports for file
 | ||||
| 	flags        []string //  ['-framework Cocoa', '-lglfw3']
 | ||||
| 	cflags       []CFlag  // ['-framework Cocoa', '-lglfw3']
 | ||||
| 	fn_cnt       int //atomic
 | ||||
| 	obfuscate    bool | ||||
| } | ||||
|  | @ -78,8 +78,6 @@ mut: | |||
| 	scope_level     int | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| struct Type { | ||||
| mut: | ||||
| 	mod            string | ||||
|  | @ -106,7 +104,6 @@ struct TypeNode { | |||
| 	typ Type | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // For debugging types
 | ||||
| fn (t Type) str() string { | ||||
| 	mut s := 'type "$t.name" {' | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue