parser: do not allow duplicate methods; builder: cleaning up

pull/4274/head
Alexander Medvednikov 2020-04-07 01:02:48 +02:00
parent 8d150d427a
commit b7560fe4bf
3 changed files with 39 additions and 82 deletions

View File

@ -11,59 +11,6 @@ import (
strings
)
/*
pub struct V {
pub mut:
mod_file_cacher &builder.ModFileCacher // used during lookup for v.mod to support @VROOT
out_name_c string // name of the temporary C file
files []string // all V files that need to be parsed and compiled
compiled_dir string // contains os.real_path() of the dir of the final file beeing compiled, or the dir itself when doing `v .`
pref &pref.Preferences // all the preferences and settings extracted to a struct for reusability
vgen_buf strings.Builder // temporary buffer for generated V code (.str() etc)
file_parser_idx map[string]int // map absolute file path to v.parsers index
gen_parser_idx map[string]int
cached_mods []string
module_lookup_paths []string
v_fmt_all bool // << input set by cmd/tools/vfmt.v
v_fmt_file string // << file given by the user from cmd/tools/vfmt.v
v_fmt_file_result string // >> file with formatted output generated by vlib/compiler/vfmt.v
}
pub fn new_v(pref &pref.Preferences) &V {
rdir := os.real_path(pref.path)
mut out_name_c := get_vtmp_filename(pref.out_name, '.tmp.c')
if pref.is_so {
out_name_c = get_vtmp_filename(pref.out_name, '.tmp.so.c')
}
mut vgen_buf := strings.new_builder(1000)
vgen_buf.writeln('module vgen\nimport strings')
compiled_dir:=if os.is_dir(rdir) { rdir } else { os.dir(rdir) }
return &V{
mod_file_cacher: builder.new_mod_file_cacher()
compiled_dir:compiled_dir// if os.is_dir(rdir) { rdir } else { os.dir(rdir) }
out_name_c: out_name_c
pref: pref
vgen_buf: vgen_buf
}
}
*/
/*
// make v2 from v1
fn (v &V) new_v2() builder.Builder {
mut b := builder.new_builder(v.pref)
b = { b|
os: v.pref.os,
module_path: pref.default_module_path,
compiled_dir: v.compiled_dir,
module_search_paths: v.module_lookup_paths
}
return b
}
*/
fn get_vtmp_folder() string {
vtmp := os.join_path(os.temp_dir(), 'v')
if !os.is_dir(vtmp) {
@ -76,8 +23,7 @@ fn get_vtmp_folder() string {
fn get_vtmp_filename(base_file_name, postfix string) string {
vtmp := get_vtmp_folder()
return os.real_path(os.join_path(vtmp, os.file_name(os.real_path(base_file_name)) +
postfix))
return os.real_path(os.join_path(vtmp, os.file_name(os.real_path(base_file_name)) + postfix))
}
pub fn compile(command string, pref &pref.Preferences) {
@ -109,7 +55,7 @@ pub fn compile(command string, pref &pref.Preferences) {
// v.add_v_files_to_compile()
// v.files << v.dir
// v2 compiler
//b.set_module_lookup_paths()
// b.set_module_lookup_paths()
files << b.get_builtin_files()
files << b.get_user_files()
b.set_module_lookup_paths()
@ -117,7 +63,7 @@ pub fn compile(command string, pref &pref.Preferences) {
println('all .v files:')
println(files)
}
//b.build_c(files, b.out_name_c) // v.pref.out_name + '.c')
// b.build_c(files, b.out_name_c) // v.pref.out_name + '.c')
b.build_c(files, pref.out_name + '.c')
b.cc()
}
@ -196,9 +142,9 @@ fn (v mut Builder) set_module_lookup_paths() {
}
}
pub fn (v &Builder) get_builtin_files() []string {
//println('get_builtin_files() lookuppath:')
//println(v.pref.lookup_path)
pub fn (v Builder) get_builtin_files() []string {
// println('get_builtin_files() lookuppath:')
// println(v.pref.lookup_path)
// Lookup for built-in folder in lookup path.
// Assumption: `builtin/` folder implies usable implementation of builtin
for location in v.pref.lookup_path {
@ -219,7 +165,7 @@ Did you forget to add vlib to the path? (Use @vlib for default vlib)')
panic('Unreachable code reached.')
}
pub fn (v &Builder) get_user_files() []string {
pub fn (v Builder) get_user_files() []string {
mut dir := v.pref.path
v.log('get_v_files($dir)')
// Need to store user files separately, because they have to be added after
@ -297,4 +243,3 @@ pub fn (v &Builder) get_user_files() []string {
}
return user_files
}

View File

@ -652,6 +652,12 @@ fn (c mut Checker) stmt(node ast.Stmt) {
c.expected_type = table.void_type
}
ast.FnDecl {
//if it.is_method {
//sym := c.table.get_type_symbol(it.receiver.typ)
//if sym.has_method(it.name) {
//c.warn('duplicate method `$it.name`', it.pos)
//}
//}
c.expected_type = table.void_type
c.fn_return_type = it.return_type
c.stmts(it.stmts)

View File

@ -12,7 +12,13 @@ import (
pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
tok := p.tok
name := p.check_name()
fn_name := if is_c { 'C.$name' } else if mod.len > 0 { '${mod}.$name' } else { name }
fn_name := if is_c {
'C.$name'
} else if mod.len > 0 {
'${mod}.$name'
} else {
name
}
p.check(.lpar)
args := p.call_args()
mut or_stmts := []ast.Stmt
@ -33,13 +39,12 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
node := ast.CallExpr{
name: fn_name
args: args
// tok: tok
mod: p.mod
pos: tok.position()
is_c: is_c
or_block: ast.OrExpr{
stmts: or_stmts
}
stmts: or_stmts
}
}
return node
}
@ -111,9 +116,12 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
if !is_c && !p.pref.translated && scanner.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) {
p.warn('duplicate method `$name`')
}
}
if p.tok.kind in [.plus, .minus, .mul, .div, .mod] {
name = p.tok.kind.str() // op_to_fn_name()
name = p.tok.kind.str() // op_to_fn_name()
p.next()
}
// <T>
@ -123,7 +131,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
p.check(.gt)
}
// Args
args2,is_variadic := p.fn_args()
args2, is_variadic := p.fn_args()
args << args2
for arg in args {
p.scope.register(arg.name, ast.Var{
@ -146,12 +154,10 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
return_type: return_type
is_variadic: is_variadic
})
}
else {
} else {
if is_c {
name = 'C.$name'
}
else {
} else {
name = p.prepend_mod(name)
}
p.table.register_fn(table.Fn{
@ -178,9 +184,9 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
is_pub: is_pub
is_variadic: is_variadic
receiver: ast.Field{
name: rec_name
typ: rec_type
}
name: rec_name
typ: rec_type
}
is_method: is_method
rec_mut: rec_mut
is_c: is_c
@ -189,14 +195,15 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
}
}
fn (p mut Parser) fn_args() ([]table.Arg,bool) {
fn (p mut Parser) fn_args() ([]table.Arg, bool) {
p.check(.lpar)
mut args := []table.Arg
mut is_variadic := false
// `int, int, string` (no names, just types)
types_only := p.tok.kind in [.amp, .and] || (p.peek_tok.kind == .comma && p.table.known_type(p.tok.lit)) || p.peek_tok.kind == .rpar
types_only := p.tok.kind in [.amp, .and] || (p.peek_tok.kind == .comma && p.table.known_type(p.tok.lit)) ||
p.peek_tok.kind == .rpar
if types_only {
//p.warn('types only')
// p.warn('types only')
mut arg_no := 1
for p.tok.kind != .rpar {
arg_name := 'arg_$arg_no'
@ -225,8 +232,7 @@ fn (p mut Parser) fn_args() ([]table.Arg,bool) {
}
arg_no++
}
}
else {
} else {
for p.tok.kind != .rpar {
mut arg_names := [p.check_name()]
// `a, b, c int`
@ -263,9 +269,9 @@ fn (p mut Parser) fn_args() ([]table.Arg,bool) {
}
}
p.check(.rpar)
return args,is_variadic
return args, is_variadic
}
fn (p &Parser) fileis(s string) bool {
fn (p Parser) fileis(s string) bool {
return p.file_name.contains(s)
}