parser: skip comp_if when building for a different compiler

pull/5420/head
spaceface777 2020-06-18 22:01:00 +02:00 committed by GitHub
parent 5ddb129bc2
commit 68967e833d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 31 deletions

View File

@ -45,7 +45,8 @@ fn test_fmt() {
}
table := table.new_table()
file_ast := parser.parse_file(ipath, table, .parse_comments, &pref.Preferences{
is_fmt: true
is_fmt: true,
ccompiler: 'gcc'
}, &ast.Scope{
parent: 0
})

View File

@ -13,6 +13,7 @@ import vweb.tmpl
const (
supported_platforms = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd',
'netbsd', 'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos']
supported_ccompilers = ['tinyc', 'clang', 'mingw', 'msvc', 'gcc']
)
fn (mut p Parser) resolve_vroot(flag string) string {
@ -154,45 +155,55 @@ fn (mut p Parser) comp_if() ast.Stmt {
}
val := p.check_name()
mut stmts := []ast.Stmt{}
mut skip_os := false
mut skip := false
if val in supported_platforms {
os := os_from_string(val)
// `$if os {` for a different target, skip everything inside
// to avoid compilation errors (like including <windows.h> or calling WinAPI fns
// on non-Windows systems)
if !p.pref.is_fmt && ((!is_not && os != p.pref.os) || (is_not && os == p.pref.os)) &&
!p.pref.output_cross_c {
skip_os = true
p.check(.lcbr)
// p.warn('skipping $if $val os=$os p.pref.os=$p.pref.os')
mut stack := 1
for {
if p.tok.kind == .key_return {
p.returns = true
}
if p.tok.kind == .lcbr {
stack++
} else if p.tok.kind == .rcbr {
stack--
}
if p.tok.kind == .eof {
break
}
if stack <= 0 && p.tok.kind == .rcbr {
// p.warn('exiting $stack')
p.next()
break
}
p.next()
}
if (!is_not && os != p.pref.os) || (is_not && os == p.pref.os) {
skip = true
}
} else if val in supported_ccompilers {
cc := cc_from_string(val)
user_cc := cc_from_string(p.pref.ccompiler)
if (!is_not && cc != user_cc) || (is_not && cc == user_cc) {
skip = true
}
}
// `$if os {` or `$if compiler {` for a different target, skip everything inside
// to avoid compilation errors (like including <windows.h> or calling WinAPI fns
// on non-Windows systems)
if !p.pref.is_fmt && !p.pref.output_cross_c && skip {
p.check(.lcbr)
// p.warn('skipping $if $val os=$os p.pref.os=$p.pref.os')
mut stack := 1
for {
if p.tok.kind == .key_return {
p.returns = true
}
if p.tok.kind == .lcbr {
stack++
} else if p.tok.kind == .rcbr {
stack--
}
if p.tok.kind == .eof {
break
}
if stack <= 0 && p.tok.kind == .rcbr {
// p.warn('exiting $stack')
p.next()
break
}
p.next()
}
} else { skip = false }
mut is_opt := false
if p.tok.kind == .question {
p.next()
is_opt = true
}
if !skip_os {
if !skip {
stmts = p.parse_block()
}
mut node := ast.CompIf{
@ -269,6 +280,17 @@ fn os_from_string(os string) pref.OS {
return .linux
}
// Helper function to convert string names to CC enum
pub fn cc_from_string(cc_str string) pref.CompilerType {
cc := cc_str.replace('\\', '/').split('/').last().all_before('.')
if 'tcc' in cc { return .tinyc }
if 'tinyc' in cc { return .tinyc }
if 'clang' in cc { return .clang }
if 'mingw' in cc { return .mingw }
if 'msvc' in cc { return .msvc }
return .gcc
}
// `app.$action()` (`action` is a string)
// `typ` is `App` in this example
// fn (mut p Parser) comptime_method_call(typ table.Type) ast.ComptimeCall {

View File

@ -32,6 +32,14 @@ pub enum Backend {
x64 // The x64 backend
}
pub enum CompilerType {
tinyc
clang
mingw
msvc
gcc
}
const (
list_of_flags_with_param = [
'o'