diff --git a/vlib/v/checker/tests/no_fn_main.out b/vlib/v/checker/tests/no_fn_main.out deleted file mode 100644 index e4b2e00a68..0000000000 --- a/vlib/v/checker/tests/no_fn_main.out +++ /dev/null @@ -1,5 +0,0 @@ -vlib/v/checker/tests/no_fn_main.v:1:1: error: function `main` must be declared in the main module - 1 | fn no_main() { - | ^ - 2 | println('Hello world !') - 3 | } diff --git a/vlib/v/checker/tests/no_fn_main.vv b/vlib/v/checker/tests/no_fn_main.vv deleted file mode 100644 index d9a0b24dae..0000000000 --- a/vlib/v/checker/tests/no_fn_main.vv +++ /dev/null @@ -1,3 +0,0 @@ -fn no_main() { - println('Hello world !') -} diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 1b759f8f2f..f3402a0457 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -401,3 +401,18 @@ fn (mut p Parser) fn_redefinition_error(name string) { */ p.error('redefinition of function `$name`') } + +fn have_fn_main(stmts []ast.Stmt) bool { + mut has_main_fn := false + for stmt in stmts { + match stmt { + ast.FnDecl { + if it.name == 'main' { + has_main_fn = true + } + } + else {} + } + } + return has_main_fn +} diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index e5e02645cc..575cd3c3aa 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -63,7 +63,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt { return p.stmt() } -pub fn parse_file(path string, table &table.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File { +pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File { // println('parse_file("$path")') // text := os.read_file(path) or { // panic(err) @@ -71,7 +71,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment mut stmts := []ast.Stmt{} mut p := Parser{ scanner: scanner.new_scanner_file(path, comments_mode) - table: table + table: b_table file_name: path file_name_dir: os.dir(path) pref: pref @@ -102,9 +102,13 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment */ // TODO: import only mode for { - // res := s.scan() if p.tok.kind == .eof { - // println('EOF, breaking') + if p.pref.is_script && !p.pref.is_test && p.mod == 'main' && !have_fn_main(stmts) { + stmts << ast.FnDecl { + name: 'main' + return_type: table.void_type + } + } break } // println('stmt at ' + p.tok.str()) @@ -350,7 +354,7 @@ pub fn (mut p Parser) top_stmt() ast.Stmt { } else { if p.pref.is_script && !p.pref.is_test { - p.scanner.add_fn_main_and_rescan() + p.scanner.add_fn_main_and_rescan(p.tok.pos-1) p.read_first_token() return p.top_stmt() } else { diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index a726d71fe9..c3d38c8002 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -75,12 +75,17 @@ pub fn new_scanner(text string, comments_mode CommentsMode) &Scanner { return s } -pub fn (s &Scanner) add_fn_main_and_rescan() { - s.text = 'fn main() {' + s.text + '}' - s.is_started = false - s.pos = 0 - s.line_nr = 0 - s.last_nl_pos = 0 +pub fn (s &Scanner) add_fn_main_and_rescan(pos int) { + if pos > 0 { + s.text = s.text[..pos] + 'fn main() {' + s.text[pos..] + '}' + s.pos = pos + s.is_started = false + } else { + s.text = 'fn main() {' + s.text + '}' + s.pos = 0 + s.line_nr = 0 + s.is_started = false + } } fn (s &Scanner) new_token(tok_kind token.Kind, lit string, len int) token.Token { diff --git a/vlib/v/tests/repl/array.repl b/vlib/v/tests/repl/array.repl new file mode 100644 index 0000000000..40fdfa1e87 --- /dev/null +++ b/vlib/v/tests/repl/array.repl @@ -0,0 +1,7 @@ +mut a := [1, 2, 3] +b := [4, 5] +a << b +a = a.filter(it%2==0) +a +===output=== +[2, 4] diff --git a/vlib/v/tests/repl/import.repl b/vlib/v/tests/repl/import.repl new file mode 100644 index 0000000000..dd3569b63e --- /dev/null +++ b/vlib/v/tests/repl/import.repl @@ -0,0 +1,4 @@ +import time +time.now().unix_time() > 160000 +===output=== +true