fix single file programs without `fn main` and REPL (allow imports,
function definitions, consts, etc)pull/751/head
parent
fd9163f715
commit
bd49977feb
|
@ -84,8 +84,8 @@ fn (f mut Fn) register_var(v Var) {
|
|||
}
|
||||
else {
|
||||
f.local_vars[f.var_idx] = new_var
|
||||
f.var_idx++
|
||||
}
|
||||
f.var_idx++
|
||||
}
|
||||
|
||||
// vlib header file?
|
||||
|
|
|
@ -343,7 +343,7 @@ string _STR_TMP(const char *fmt, ...) {
|
|||
if !c.table.main_exists() && !c.is_test {
|
||||
// It can be skipped in single file programs
|
||||
if c.is_script {
|
||||
println('Generating main()...')
|
||||
//println('Generating main()...')
|
||||
cgen.genln('int main() { $cgen.fn_main; return 0; }')
|
||||
}
|
||||
else {
|
||||
|
@ -372,14 +372,14 @@ string _STR_TMP(const char *fmt, ...) {
|
|||
cgen.genln('return 1; }')
|
||||
}
|
||||
cgen.save()
|
||||
c.log('flags=')
|
||||
if c.is_verbose {
|
||||
c.log('flags=')
|
||||
println(c.table.flags)
|
||||
}
|
||||
c.cc()
|
||||
if c.is_test || c.is_run {
|
||||
if true || c.is_verbose {
|
||||
println('============running $c.out_name==============================')
|
||||
println('============ running $c.out_name ============')
|
||||
}
|
||||
mut cmd := if c.out_name.starts_with('/') {
|
||||
c.out_name
|
||||
|
@ -866,10 +866,9 @@ fn run_repl() []string {
|
|||
// but don't add this print call to the `lines` array,
|
||||
// so that it doesn't get called during the next print.
|
||||
if line.starts_with('print') {
|
||||
// TODO remove this once files without main compile correctly
|
||||
void_line := line.substr(line.index('(') + 1, line.len - 1)
|
||||
lines << void_line
|
||||
source_code := 'fn main(){' + lines.join('\n') + '\n' + line + '}'
|
||||
source_code := lines.join('\n') + '\n' + line
|
||||
os.write_file(file, source_code)
|
||||
mut v := new_v( ['v', '-repl', file])
|
||||
v.compile()
|
||||
|
|
|
@ -77,6 +77,7 @@ mut:
|
|||
|
||||
const (
|
||||
EmptyFn = &Fn { }
|
||||
MainFn= &Fn{name:'main'}
|
||||
)
|
||||
|
||||
fn (c mut V) new_parser(path string, run Pass) Parser {
|
||||
|
@ -225,7 +226,7 @@ fn (p mut Parser) parse() {
|
|||
g += p.cgen.end_tmp()
|
||||
}
|
||||
// p.genln('; // global')
|
||||
g += ('; // global')
|
||||
g += '; // global'
|
||||
p.cgen.consts << g
|
||||
case EOF:
|
||||
p.log('end of parse()')
|
||||
|
@ -238,25 +239,29 @@ fn (p mut Parser) parse() {
|
|||
default:
|
||||
// no `fn main`, add this "global" statement to cgen.fn_main
|
||||
if p.is_script && !p.is_test {
|
||||
if p.cur_fn.scope_level == 0 {
|
||||
// p.cur_fn.scope_level++
|
||||
// cur_fn is empty since there was no fn main declared
|
||||
// we need to set it to save and find variables
|
||||
if p.first_run() {
|
||||
if p.cur_fn.name == '' {
|
||||
p.cur_fn = MainFn
|
||||
}
|
||||
return
|
||||
}
|
||||
if p.cur_fn.name == '' {
|
||||
p.cur_fn = MainFn
|
||||
}
|
||||
// println('is script')
|
||||
p.print_tok()
|
||||
start := p.cgen.lines.len
|
||||
p.statement(true)
|
||||
p.genln('')
|
||||
end := p.cgen.lines.len
|
||||
lines := p.cgen.lines.slice(start, end)
|
||||
// p.cgen.fn_main << p.cgen.prev_line
|
||||
// println('fn line:')
|
||||
// println(p.cgen.fn_main + lines.join('\n'))
|
||||
//mut line := p.cgen.fn_main + lines.join('\n')
|
||||
//line = line.trim_space()
|
||||
p.cgen.fn_main = p.cgen.fn_main + lines.join('\n')
|
||||
p.cgen.cur_line = ''
|
||||
for i := start; i < end; i++ {
|
||||
// p.cgen.lines[p.cgen.lines.len - 1] = ''
|
||||
p.cgen.lines[i] = ''
|
||||
}
|
||||
// exit('')
|
||||
}
|
||||
else {
|
||||
p.error('unexpected token `${p.strtok()}`')
|
||||
|
@ -664,13 +669,14 @@ fn (p mut Parser) error(s string) {
|
|||
p.cgen.save()
|
||||
// V git pull hint
|
||||
cur_path := os.getwd()
|
||||
if p.file_path.contains('v/compiler') || cur_path.contains('v/compiler') {
|
||||
if !p.is_repl && ( p.file_path.contains('v/compiler') || cur_path.contains('v/compiler') ){
|
||||
println('\n=========================')
|
||||
println('It looks like you are building V. It is being frequently updated every day.')
|
||||
println('If you didn\'t modify the compiler\'s code, most likely there was a change that ')
|
||||
println('lead to this error.')
|
||||
println('\nTry to run `git pull && make clean && make`, that will most likely fix it.')
|
||||
println('\nIf this doesn\'t help, re-install V from source or download a precompiled' + ' binary from\nhttps://vlang.io.')
|
||||
println('\nRun `git pull && make`, that will most likely fix it.')
|
||||
//println('\nIf this doesn\'t help, re-install V from source or download a precompiled' + ' binary from\nhttps://vlang.io.')
|
||||
println('\nIf this doesn\'t help, please create a GitHub issue.')
|
||||
println('=========================\n')
|
||||
}
|
||||
// p.scanner.debug_tokens()
|
||||
|
@ -1349,9 +1355,7 @@ fn (p mut Parser) name_expr() string {
|
|||
// Function (not method btw, methods are handled in dot())
|
||||
f := p.table.find_fn(name)
|
||||
if f.name == '' {
|
||||
println(p.cur_fn.name)
|
||||
println(p.cur_fn.args.len)
|
||||
// if !p.first_run() && !p.translated {
|
||||
// We are in a second pass, that means this function was not defined, throw an error.
|
||||
if !p.first_run() {
|
||||
// println('name_expr():')
|
||||
// If orig_name is a pkg, then printing undefined: `pkg` tells us nothing
|
||||
|
|
|
@ -210,7 +210,7 @@ fn (table &Table) known_type(typ string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// TODO PERF O(N) this slows down the comiler a lot!
|
||||
// TODO PERF O(N) this slows down the compiler a lot!
|
||||
fn (t &Table) find_fn(name string) Fn {
|
||||
for f in t.fns {
|
||||
if f.name == name {
|
||||
|
@ -220,7 +220,7 @@ fn (t &Table) find_fn(name string) Fn {
|
|||
return Fn{}
|
||||
}
|
||||
|
||||
// TODO PERF O(N) this slows down the comiler a lot!
|
||||
// TODO PERF O(N) this slows down the compiler a lot!
|
||||
fn (t &Table) known_fn(name string) bool {
|
||||
for f in t.fns {
|
||||
if f.name == name {
|
||||
|
@ -249,10 +249,9 @@ fn (t mut Table) register_type(typ string) {
|
|||
// if t.types.filter( _.name == typ.name).len > 0 {
|
||||
// return
|
||||
// }
|
||||
datyp := Type {
|
||||
t.types << Type {
|
||||
name: typ
|
||||
}
|
||||
t.types << datyp
|
||||
}
|
||||
|
||||
fn (p mut Parser) register_type_with_parent(strtyp, parent string) {
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
println('Hello, World!')
|
||||
|
||||
|
|
Loading…
Reference in New Issue