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 {
|
else {
|
||||||
f.local_vars[f.var_idx] = new_var
|
f.local_vars[f.var_idx] = new_var
|
||||||
f.var_idx++
|
|
||||||
}
|
}
|
||||||
|
f.var_idx++
|
||||||
}
|
}
|
||||||
|
|
||||||
// vlib header file?
|
// vlib header file?
|
||||||
|
|
|
@ -343,7 +343,7 @@ string _STR_TMP(const char *fmt, ...) {
|
||||||
if !c.table.main_exists() && !c.is_test {
|
if !c.table.main_exists() && !c.is_test {
|
||||||
// It can be skipped in single file programs
|
// It can be skipped in single file programs
|
||||||
if c.is_script {
|
if c.is_script {
|
||||||
println('Generating main()...')
|
//println('Generating main()...')
|
||||||
cgen.genln('int main() { $cgen.fn_main; return 0; }')
|
cgen.genln('int main() { $cgen.fn_main; return 0; }')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -372,14 +372,14 @@ string _STR_TMP(const char *fmt, ...) {
|
||||||
cgen.genln('return 1; }')
|
cgen.genln('return 1; }')
|
||||||
}
|
}
|
||||||
cgen.save()
|
cgen.save()
|
||||||
c.log('flags=')
|
|
||||||
if c.is_verbose {
|
if c.is_verbose {
|
||||||
|
c.log('flags=')
|
||||||
println(c.table.flags)
|
println(c.table.flags)
|
||||||
}
|
}
|
||||||
c.cc()
|
c.cc()
|
||||||
if c.is_test || c.is_run {
|
if c.is_test || c.is_run {
|
||||||
if true || c.is_verbose {
|
if true || c.is_verbose {
|
||||||
println('============running $c.out_name==============================')
|
println('============ running $c.out_name ============')
|
||||||
}
|
}
|
||||||
mut cmd := if c.out_name.starts_with('/') {
|
mut cmd := if c.out_name.starts_with('/') {
|
||||||
c.out_name
|
c.out_name
|
||||||
|
@ -866,10 +866,9 @@ fn run_repl() []string {
|
||||||
// but don't add this print call to the `lines` array,
|
// but don't add this print call to the `lines` array,
|
||||||
// so that it doesn't get called during the next print.
|
// so that it doesn't get called during the next print.
|
||||||
if line.starts_with('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)
|
void_line := line.substr(line.index('(') + 1, line.len - 1)
|
||||||
lines << void_line
|
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)
|
os.write_file(file, source_code)
|
||||||
mut v := new_v( ['v', '-repl', file])
|
mut v := new_v( ['v', '-repl', file])
|
||||||
v.compile()
|
v.compile()
|
||||||
|
|
|
@ -77,6 +77,7 @@ mut:
|
||||||
|
|
||||||
const (
|
const (
|
||||||
EmptyFn = &Fn { }
|
EmptyFn = &Fn { }
|
||||||
|
MainFn= &Fn{name:'main'}
|
||||||
)
|
)
|
||||||
|
|
||||||
fn (c mut V) new_parser(path string, run Pass) Parser {
|
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()
|
g += p.cgen.end_tmp()
|
||||||
}
|
}
|
||||||
// p.genln('; // global')
|
// p.genln('; // global')
|
||||||
g += ('; // global')
|
g += '; // global'
|
||||||
p.cgen.consts << g
|
p.cgen.consts << g
|
||||||
case EOF:
|
case EOF:
|
||||||
p.log('end of parse()')
|
p.log('end of parse()')
|
||||||
|
@ -238,25 +239,29 @@ fn (p mut Parser) parse() {
|
||||||
default:
|
default:
|
||||||
// no `fn main`, add this "global" statement to cgen.fn_main
|
// no `fn main`, add this "global" statement to cgen.fn_main
|
||||||
if p.is_script && !p.is_test {
|
if p.is_script && !p.is_test {
|
||||||
if p.cur_fn.scope_level == 0 {
|
// cur_fn is empty since there was no fn main declared
|
||||||
// p.cur_fn.scope_level++
|
// 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
|
start := p.cgen.lines.len
|
||||||
p.statement(true)
|
p.statement(true)
|
||||||
|
p.genln('')
|
||||||
end := p.cgen.lines.len
|
end := p.cgen.lines.len
|
||||||
lines := p.cgen.lines.slice(start, end)
|
lines := p.cgen.lines.slice(start, end)
|
||||||
// p.cgen.fn_main << p.cgen.prev_line
|
//mut line := p.cgen.fn_main + lines.join('\n')
|
||||||
// println('fn line:')
|
//line = line.trim_space()
|
||||||
// println(p.cgen.fn_main + lines.join('\n'))
|
|
||||||
p.cgen.fn_main = p.cgen.fn_main + lines.join('\n')
|
p.cgen.fn_main = p.cgen.fn_main + lines.join('\n')
|
||||||
p.cgen.cur_line = ''
|
p.cgen.cur_line = ''
|
||||||
for i := start; i < end; i++ {
|
for i := start; i < end; i++ {
|
||||||
// p.cgen.lines[p.cgen.lines.len - 1] = ''
|
|
||||||
p.cgen.lines[i] = ''
|
p.cgen.lines[i] = ''
|
||||||
}
|
}
|
||||||
// exit('')
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p.error('unexpected token `${p.strtok()}`')
|
p.error('unexpected token `${p.strtok()}`')
|
||||||
|
@ -664,13 +669,14 @@ fn (p mut Parser) error(s string) {
|
||||||
p.cgen.save()
|
p.cgen.save()
|
||||||
// V git pull hint
|
// V git pull hint
|
||||||
cur_path := os.getwd()
|
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('\n=========================')
|
||||||
println('It looks like you are building V. It is being frequently updated every day.')
|
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('If you didn\'t modify the compiler\'s code, most likely there was a change that ')
|
||||||
println('lead to this error.')
|
println('lead to this error.')
|
||||||
println('\nTry to run `git pull && make clean && make`, that will most likely fix it.')
|
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, 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')
|
println('=========================\n')
|
||||||
}
|
}
|
||||||
// p.scanner.debug_tokens()
|
// p.scanner.debug_tokens()
|
||||||
|
@ -1349,9 +1355,7 @@ fn (p mut Parser) name_expr() string {
|
||||||
// Function (not method btw, methods are handled in dot())
|
// Function (not method btw, methods are handled in dot())
|
||||||
f := p.table.find_fn(name)
|
f := p.table.find_fn(name)
|
||||||
if f.name == '' {
|
if f.name == '' {
|
||||||
println(p.cur_fn.name)
|
// We are in a second pass, that means this function was not defined, throw an error.
|
||||||
println(p.cur_fn.args.len)
|
|
||||||
// if !p.first_run() && !p.translated {
|
|
||||||
if !p.first_run() {
|
if !p.first_run() {
|
||||||
// println('name_expr():')
|
// println('name_expr():')
|
||||||
// If orig_name is a pkg, then printing undefined: `pkg` tells us nothing
|
// 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
|
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 {
|
fn (t &Table) find_fn(name string) Fn {
|
||||||
for f in t.fns {
|
for f in t.fns {
|
||||||
if f.name == name {
|
if f.name == name {
|
||||||
|
@ -220,7 +220,7 @@ fn (t &Table) find_fn(name string) Fn {
|
||||||
return 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 {
|
fn (t &Table) known_fn(name string) bool {
|
||||||
for f in t.fns {
|
for f in t.fns {
|
||||||
if f.name == name {
|
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 {
|
// if t.types.filter( _.name == typ.name).len > 0 {
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
datyp := Type {
|
t.types << Type {
|
||||||
name: typ
|
name: typ
|
||||||
}
|
}
|
||||||
t.types << datyp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) register_type_with_parent(strtyp, parent string) {
|
fn (p mut Parser) register_type_with_parent(strtyp, parent string) {
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
println('Hello, World!')
|
println('Hello, World!')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue