diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 9d7d8b5c0c..86d01a26a7 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -83,6 +83,7 @@ mut: comptime_if_cond bool defer_vars []ast.Ident should_abort bool // when too many errors/warnings/notices are accumulated, should_abort becomes true, and the parser should stop + codegen_text string } // for tests @@ -305,6 +306,13 @@ pub fn (mut p Parser) parse() &ast.File { notices << p.scanner.notices } + // codegen + if p.codegen_text.len > 0 && !p.pref.is_fmt { + ptext := 'module ' + p.mod.all_after('.') + p.codegen_text + codegen_file := parse_text(ptext, p.file_name, p.table, p.comments_mode, p.pref) + stmts << codegen_file.stmts + } + return &ast.File{ path: p.file_name path_base: p.file_base @@ -396,6 +404,15 @@ pub fn parse_files(paths []string, table &ast.Table, pref &pref.Preferences) []& return files } +// codegen allows you to generate V code, so that it can be parsed, +// checked, markused, cgen-ed etc further, just like user's V code. +pub fn (mut p Parser) codegen(code string) { + $if debug_codegen ? { + eprintln('parser.codegen:\n $code') + } + p.codegen_text += '\n' + code +} + pub fn (mut p Parser) init_parse_fns() { // p.prefix_parse_fns = make(100, 100, sizeof(PrefixParseFn)) // p.prefix_parse_fns[token.Kind.name] = parse_name @@ -3309,7 +3326,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl { } } pubfn := if p.mod == 'main' { 'fn' } else { 'pub fn' } - p.scanner.codegen(' + p.codegen(' // [inline] $pubfn ( e &$enum_name) is_empty() bool { return int(*e) == 0 } [inline] $pubfn ( e &$enum_name) has(flag $enum_name) bool { return (int(*e) & (int(flag))) != 0 } diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 3f2fa710d6..1dae5ff435 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1460,27 +1460,6 @@ pub fn verror(s string) { util.verror('scanner error', s) } -// codegen allows you to generate V code, so that it can be parsed, -// checked, markused, cgen-ed etc further, just like user's V code. -pub fn (mut s Scanner) codegen(newtext string) { - $if debug_codegen ? { - eprintln('scanner.codegen:\n $newtext') - } - if s.comments_mode == .skip_comments { - // Calling codegen makes sense only during normal compilation, since - // feeding code generated V code to vfmt or vdoc will cause them to - // output/document ephemeral stuff. - for s.all_tokens.len > 0 && s.all_tokens.last().kind == .eof { - s.all_tokens.delete_last() - } - s.text += newtext - old_tidx := s.tidx - s.tidx = s.all_tokens.len - s.scan_remaining_text() - s.tidx = old_tidx - } -} - fn (mut s Scanner) trace(fbase string, message string) { if s.file_base == fbase { println('> s.trace | ${fbase:-10s} | $message')