all: replace `is_c`, `is_js` with `language`

pull/4907/head
spaceface777 2020-05-19 17:12:47 +02:00 committed by GitHub
parent 74686d0ec4
commit b10df252dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 114 additions and 93 deletions

View File

@ -15,8 +15,7 @@ import vhelp
struct FormatOptions {
is_l bool
is_c bool
is_js bool
is_c bool // NB: This refers to the '-c' fmt flag, NOT the C backend
is_w bool
is_diff bool
is_verbose bool
@ -44,7 +43,6 @@ fn main() {
args := util.join_env_vflags_and_os_args()
foptions := FormatOptions{
is_c: '-c' in args
is_js: '-js' in args
is_l: '-l' in args
is_w: '-w' in args
is_diff: '-diff' in args
@ -197,7 +195,7 @@ fn (foptions &FormatOptions) post_process_file(file, formatted_file_path string)
return
}
is_formatted_different := fc != formatted_fc
if foptions.is_c || foptions.is_js {
if foptions.is_c {
if is_formatted_different {
eprintln('File is not formatted: $file')
exit(2)

View File

@ -61,11 +61,10 @@ pub:
pub struct StringLiteral {
pub:
val string
is_raw bool
is_c bool
is_js bool
pos token.Position
val string
is_raw bool
language table.Language
pos token.Position
}
// 'name: $name'
@ -160,8 +159,7 @@ pub:
mut_pos int // mut:
pub_pos int // pub:
pub_mut_pos int // pub mut:
is_c bool
is_js bool
language table.Language
is_union bool
attr string
}
@ -221,8 +219,7 @@ pub:
receiver_pos token.Position
is_method bool
rec_mut bool // is receiver mutable
is_c bool
is_js bool
language table.Language
no_body bool // just a definition `fn C.malloc()`
is_builtin bool // this function is defined in builtin/strconv
ctdefine string // has [if myflag] tag
@ -248,8 +245,7 @@ pub mut:
is_method bool
args []CallArg
expected_arg_types []table.Type
is_c bool
is_js bool
language table.Language
or_block OrExpr
left_type table.Type // type of `user`
receiver_type table.Type // User
@ -349,8 +345,7 @@ pub enum IdentKind {
pub struct Ident {
pub:
value string
is_c bool
is_js bool
language table.Language
tok_kind token.Kind
mod string
pos token.Position

View File

@ -31,10 +31,10 @@ pub fn (node &FnDecl) str(t &table.Table) string {
*/
}
mut name := if node.is_anon { '' } else { node.name.after('.') }
if node.is_c {
if node.language == .c {
name = 'C.$name'
}
if node.is_js {
else if node.language == .js {
name = 'JS.$name'
}
f.write('fn ${receiver}${name}(')

View File

@ -202,7 +202,7 @@ fn (mut c Checker) check_valid_pascal_case(name, identifier string, pos token.Po
pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
match node {
ast.AliasTypeDecl {
// TODO Replace `c.file.mod.name != 'time'` by `it.is_c` once available
// TODO Replace `c.file.mod.name != 'time'` by `it.language != .v` once available
if c.file.mod.name != 'time' {
c.check_valid_pascal_case(it.name, 'type alias', it.pos)
}
@ -247,11 +247,11 @@ pub fn (mut c Checker) interface_decl(decl ast.InterfaceDecl) {
}
pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
if !decl.is_c && !decl.is_js && !c.is_builtin_mod {
if decl.language == .v && !c.is_builtin_mod {
c.check_valid_pascal_case(decl.name, 'struct name', decl.pos)
}
for i, field in decl.fields {
if !decl.is_c && !decl.is_js {
if decl.language == .v {
c.check_valid_snake_case(field.name, 'field name', field.pos)
}
for j in 0 .. i {
@ -260,7 +260,7 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
}
}
sym := c.table.get_type_symbol(field.typ)
if sym.kind == .placeholder && !decl.is_c && !sym.name.starts_with('C.') {
if sym.kind == .placeholder && decl.language != .c && !sym.name.starts_with('C.') {
c.error('unknown type `$sym.name`', field.pos)
}
if sym.kind == .struct_ {
@ -889,7 +889,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
call_expr.pos)
}
}
if !f.is_pub && !f.is_c && !c.is_builtin_mod && !c.pref.is_test && f.mod != c.mod && f.name !=
if !f.is_pub && f.language == .v && !c.is_builtin_mod && !c.pref.is_test && f.mod != c.mod && f.name !=
'' && f.mod != '' {
c.warn('function `$f.name` is private. curmod=$c.mod fmod=$f.mod', call_expr.pos)
}
@ -897,7 +897,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
if f.return_type == table.void_type && f.ctdefine.len > 0 && f.ctdefine !in c.pref.compile_defines {
call_expr.should_be_skipped = true
}
if f.is_c || call_expr.is_c || f.is_js || call_expr.is_js {
if f.language != .v || call_expr.language != .v {
for arg in call_expr.args {
c.expr(arg.expr)
}
@ -1176,7 +1176,7 @@ pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) {
else {
if field.expr is ast.Ident {
expr := field.expr as ast.Ident
if expr.is_c {
if expr.language == .c {
continue
}
}
@ -1768,7 +1768,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
return table.int_type
}
ast.StringLiteral {
if it.is_c {
if it.language == .c {
return table.byteptr_type
}
return table.string_type
@ -1897,7 +1897,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
return fn_type
}
}
if ident.is_c {
if ident.language == .c {
return table.int_type
}
if ident.name != '_' {
@ -2301,7 +2301,7 @@ fn (c &Checker) fileis(s string) bool {
}
fn (mut c Checker) fn_decl(it ast.FnDecl) {
if !it.is_c && !it.is_js && !c.is_builtin_mod {
if it.language == .v && !c.is_builtin_mod {
c.check_valid_snake_case(it.name, 'function name', it.pos)
}
if it.is_method {
@ -2313,7 +2313,7 @@ fn (mut c Checker) fn_decl(it ast.FnDecl) {
// c.warn('duplicate method `$it.name`', it.pos)
// }
}
if !it.is_c {
if it.language == .v {
// Make sure all types are valid
for arg in it.args {
sym := c.table.get_type_symbol(arg.typ)
@ -2325,7 +2325,7 @@ fn (mut c Checker) fn_decl(it ast.FnDecl) {
c.expected_type = table.void_type
c.fn_return_type = it.return_type
c.stmts(it.stmts)
if !it.is_c && !it.is_js && !it.no_body && it.return_type != table.void_type && !c.returns &&
if it.language == .v && !it.no_body && it.return_type != table.void_type && !c.returns &&
it.name !in ['panic', 'exit'] {
c.error('missing return at end of function `$it.name`', it.pos)
}

View File

@ -759,7 +759,7 @@ pub fn (mut f Fmt) fn_decl(node ast.FnDecl) {
// f.find_comment(it.pos.line_nr)
s := node.str(f.table)
f.write(s.replace(f.cur_mod + '.', '')) // `Expr` instead of `ast.Expr` in mod ast
if !node.is_c && !node.is_js {
if node.language == .v {
f.writeln(' {')
f.stmts(node.stmts)
f.write('}')

View File

@ -392,7 +392,7 @@ typedef struct {
is_fn_sig := func.name == ''
not_anon := !info.is_anon
if !info.has_decl && !is_multi && (not_anon || is_fn_sig) {
fn_name := if func.is_c {
fn_name := if func.language == .c {
func.name.replace('.', '__')
} else if info.is_anon {
typ.name
@ -683,14 +683,14 @@ fn (mut g Gen) stmt(node ast.Stmt) {
g.return_statement(it)
}
ast.StructDecl {
name := if it.is_c { it.name.replace('.', '__') } else { c_name(it.name) }
name := if it.language == .c { it.name.replace('.', '__') } else { c_name(it.name) }
// g.writeln('typedef struct {')
// for field in it.fields {
// field_type_sym := g.table.get_type_symbol(field.typ)
// g.writeln('\t$field_type_sym.name $field.name;')
// }
// g.writeln('} $name;')
if it.is_c {
if it.language == .c {
return
}
if it.is_union {
@ -1364,7 +1364,7 @@ fn (mut g Gen) expr(node ast.Expr) {
return
}
escaped_val := it.val.replace_each(['"', '\\"', '\r\n', '\\n', '\n', '\\n'])
if g.is_c_call || it.is_c {
if g.is_c_call || it.language == .c {
// In C calls we have to generate C strings
// `C.printf("hi")` => `printf("hi");`
g.write('"$escaped_val"')
@ -1711,7 +1711,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
g.write(')')
} else if node.op in [.plus, .minus, .mul, .div, .mod] && (left_sym.name[0].is_capital() ||
left_sym.name.contains('.')) && left_sym.kind != .alias ||
left_sym.kind == .alias && (left_sym.info as table.Alias).is_c {
left_sym.kind == .alias && (left_sym.info as table.Alias).language == .c {
// !left_sym.is_number() {
g.write(g.typ(node.left_type))
g.write('_')

View File

@ -8,7 +8,7 @@ import v.table
import v.util
fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
if it.is_c {
if it.language == .c {
// || it.no_body {
return
}
@ -56,7 +56,7 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
if it.is_method {
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
}
if it.is_c {
if it.language == .c {
name = name.replace('.', '__')
} else {
name = c_name(name)
@ -418,7 +418,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
g.gen_json_for_type(ast_type.typ)
}
}
if node.is_c {
if node.language == .c {
// Skip "C."
g.is_c_call = true
name = name[2..].replace('.', '__')

View File

@ -82,7 +82,7 @@ pub fn (mut p Parser) assign_expr(left ast.Expr) ast.AssignExpr {
fn (mut p Parser) parse_assign_ident() ast.Ident {
/// returns a single parsed ident
return p.parse_ident(false, false)
return p.parse_ident(.v)
}
// right hand side of `=` or `:=` in `a,b,c := 1,2,3`

View File

@ -8,11 +8,11 @@ import v.table
import v.token
import v.util
pub fn (mut p Parser) call_expr(is_c, is_js bool, mod string) ast.CallExpr {
pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExpr {
first_pos := p.tok.position()
fn_name := if is_c {
fn_name := if language == .c {
'C.${p.check_name()}'
} else if is_js {
} else if language == .js {
'JS.${p.check_js_name()}'
} else if mod.len > 0 {
'${mod}.${p.check_name()}'
@ -69,8 +69,7 @@ pub fn (mut p Parser) call_expr(is_c, is_js bool, mod string) ast.CallExpr {
args: args
mod: p.mod
pos: pos
is_c: is_c
is_js: is_js
language: language
or_block: ast.OrExpr{
stmts: or_stmts
is_used: is_or_block_used
@ -109,9 +108,14 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
p.check(.key_fn)
p.open_scope()
// C. || JS.
is_c := p.tok.kind == .name && p.tok.lit == 'C'
is_js := p.tok.kind == .name && p.tok.lit == 'JS'
if is_c || is_js {
language := if p.tok.kind == .name && p.tok.lit == 'C' {
table.Language.c
} else if p.tok.kind == .name && p.tok.lit == 'JS' {
table.Language.js
} else {
table.Language.v
}
if language != .v {
p.next()
p.check(.dot)
}
@ -162,12 +166,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
mut name := ''
if p.tok.kind == .name {
// TODO high order fn
name = if is_js {
name = if language == .js {
p.check_js_name()
} else {
p.check_name()
}
if !is_js && !is_c && !p.pref.translated && util.contains_capital(name) {
if language == .v && !p.pref.translated && util.contains_capital(name) {
p.error('function names cannot contain uppercase letters, use snake_case instead')
}
if is_method && p.table.get_type_symbol(rec_type).has_method(name) {
@ -235,9 +239,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
ctdefine: ctdefine
})
} else {
if is_c {
if language == .c {
name = 'C.$name'
} else if is_js {
} else if language == .js {
name = 'JS.$name'
} else {
name = p.prepend_mod(name)
@ -250,8 +254,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
args: args
return_type: return_type
is_variadic: is_variadic
is_c: is_c
is_js: is_js
language: language
is_generic: is_generic
is_pub: is_pub
ctdefine: ctdefine
@ -283,8 +286,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
receiver_pos: receiver_pos
is_method: is_method
rec_mut: rec_mut
is_c: is_c
is_js: is_js
language: language
no_body: no_body
pos: start_pos.extend(end_pos)
body_pos: body_start_pos

View File

@ -117,15 +117,22 @@ pub fn (mut p Parser) parse_type() table.Type {
}
p.next()
}
is_c := p.tok.lit == 'C'
is_js := p.tok.lit == 'JS'
if is_c || is_js {
language := if p.tok.lit == 'C' {
table.Language.c
} else if p.tok.lit == 'JS' {
table.Language.js
} else {
table.Language.v
}
if language != .v {
p.next()
p.check(.dot)
}
mut typ := table.void_type
if p.tok.kind != .lcbr {
typ = p.parse_any_type(is_c, is_js, nr_muls > 0)
typ = p.parse_any_type(language, nr_muls > 0)
}
if is_optional {
typ = typ.set_flag(.optional)
@ -136,11 +143,11 @@ pub fn (mut p Parser) parse_type() table.Type {
return typ
}
pub fn (mut p Parser) parse_any_type(is_c, is_js, is_ptr bool) table.Type {
pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool) table.Type {
mut name := p.tok.lit
if is_c {
if language == .c {
name = 'C.$name'
} else if is_js {
} else if language == .js {
name = 'JS.$name'
} else if p.peek_tok.kind == .dot {
// `module.Type`

View File

@ -22,8 +22,7 @@ mut:
peek_tok token.Token
peek_tok2 token.Token
table &table.Table
is_c bool
is_js bool
language table.Language
inside_if bool
inside_if_expr bool
inside_or_expr bool
@ -693,7 +692,7 @@ fn (mut p Parser) parse_multi_expr() ast.Stmt {
}
}
pub fn (mut p Parser) parse_ident(is_c, is_js bool) ast.Ident {
pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident {
// p.warn('name ')
is_mut := p.tok.kind == .key_mut
if is_mut {
@ -723,8 +722,7 @@ pub fn (mut p Parser) parse_ident(is_c, is_js bool) ast.Ident {
mut ident := ast.Ident{
kind: .unresolved
name: name
is_c: is_c
is_js: is_js
language: language
mod: p.mod
pos: pos
}
@ -751,8 +749,13 @@ pub fn (mut p Parser) name_expr() ast.Expr {
pos: type_pos
}
}
is_c := p.tok.lit == 'C'
is_js := p.tok.lit == 'JS'
language := if p.tok.lit == 'C' {
table.Language.c
} else if p.tok.lit == 'JS' {
table.Language.js
} else {
table.Language.v
}
mut mod := ''
// p.warn('resetting')
p.expr_mod = ''
@ -781,11 +784,11 @@ pub fn (mut p Parser) name_expr() ast.Expr {
else {}
}
}
if p.peek_tok.kind == .dot && !known_var && (is_c || is_js || p.known_import(p.tok.lit) ||
if p.peek_tok.kind == .dot && !known_var && (language != .v || p.known_import(p.tok.lit) ||
p.mod.all_after('.') == p.tok.lit) {
if is_c {
if language == .c {
mod = 'C'
} else if is_js {
} else if language == .js {
mod = 'JS'
} else {
if p.tok.lit in p.imports {
@ -840,7 +843,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
} else {
// fn call
// println('calling $p.tok.lit')
node = p.call_expr(is_c, is_js, mod)
node = p.call_expr(language, mod)
}
} else if p.peek_tok.kind == .lcbr && !p.inside_match && !p.inside_match_case && !p.inside_if &&
!p.inside_for {
@ -868,10 +871,10 @@ pub fn (mut p Parser) name_expr() ast.Expr {
// `foo(key:val, key2:val2)`
return p.struct_init(true) // short_syntax:true
// JS. function call with more than 1 dot
} else if is_js && p.peek_tok.kind == .dot && p.peek_tok2.kind == .name {
node = p.call_expr(is_c, is_js, mod)
} else if language == .js && p.peek_tok.kind == .dot && p.peek_tok2.kind == .name {
node = p.call_expr(language, mod)
} else {
node = p.parse_ident(is_c, is_js)
node = p.parse_ident(language)
}
p.expr_mod = ''
return node
@ -1041,7 +1044,7 @@ fn (mut p Parser) string_expr() ast.Expr {
node = ast.StringLiteral{
val: val
is_raw: is_raw
is_c: is_cstr
language: if is_cstr { table.Language.c } else { table.Language.v }
pos: pos
}
return node
@ -1406,6 +1409,13 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
parent_type := first_type
parent_name := p.table.get_type_symbol(parent_type).name
pid := parent_type.idx()
language := if parent_name.len > 2 && parent_name.starts_with('C.') {
table.Language.c
} else if parent_name.len > 2 && parent_name.starts_with('JS.') {
table.Language.js
} else {
table.Language.v
}
p.table.register_type_symbol(table.TypeSymbol{
kind: .alias
name: p.prepend_mod(name)
@ -1413,7 +1423,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
mod: p.mod
info: table.Alias{
parent_typ: parent_type
is_c: parent_name.len > 2 && parent_name[0] == `C` && parent_name[1] == `.`
language: language
}
is_public: is_pub
})

View File

@ -20,20 +20,25 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
} else {
p.check(.key_union)
}
is_c := p.tok.lit == 'C' && p.peek_tok.kind == .dot
is_js := p.tok.lit == 'JS' && p.peek_tok.kind == .dot
if is_c {
language := if p.tok.lit == 'C' && p.peek_tok.kind == .dot {
table.Language.c
} else if p.tok.lit == 'JS' && p.peek_tok.kind == .dot {
table.Language.js
} else {
table.Language.v
}
if language != .v {
p.next() // C || JS
p.next() // .
}
is_typedef := p.attr == 'typedef'
no_body := p.peek_tok.kind != .lcbr
if !is_c && !is_js && no_body {
if language == .v && no_body {
p.error('`$p.tok.lit` lacks body')
}
end_pos := p.tok.position()
mut name := p.check_name()
if !is_c && !is_js && p.mod != 'builtin' && name.len > 0 && !name[0].is_capital() {
if language == .v && p.mod != 'builtin' && name.len > 0 && !name[0].is_capital() {
p.error_with_pos('struct name `$name` must begin with capital letter', end_pos)
}
// println('struct decl $name')
@ -156,9 +161,9 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
}
p.check(.rcbr)
}
if is_c {
if language == .c {
name = 'C.$name'
} else if is_js {
} else if language == .js {
name = 'JS.$name'
} else {
name = p.prepend_mod(name)
@ -195,8 +200,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
mut_pos: mut_pos
pub_pos: pub_pos
pub_mut_pos: pub_mut_pos
is_c: is_c
is_js: is_js
language: language
is_union: is_union
attr: p.attr
}

View File

@ -17,6 +17,12 @@ pub type Type int
pub type TypeInfo = Alias | Array | ArrayFixed | Enum | FnType | Interface | Map | MultiReturn | Struct | SumType
pub enum Language {
v
c
js
}
pub struct TypeSymbol {
pub:
parent_idx int
@ -574,8 +580,8 @@ pub:
pub struct Alias {
pub:
parent_typ Type
is_c bool
parent_typ Type
language Language
}
// NB: FExpr here is a actually an ast.Expr .

View File

@ -21,8 +21,7 @@ pub:
args []Arg
return_type Type
is_variadic bool
is_c bool
is_js bool
language Language
is_generic bool
is_pub bool
mod string