mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
preliminary support for builtin functions, various fixes, various tweaks
This commit is contained in:
parent
74bb5ae17a
commit
1cb752f722
7
cmd/tools/builders/go_builder.v
Normal file
7
cmd/tools/builders/go_builder.v
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
import v.builder.gobuilder
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
gobuilder.start()
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
module main
|
|
||||||
|
|
||||||
import v.builder.golangbuilder
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
golangbuilder.start()
|
|
||||||
}
|
|
@ -176,9 +176,9 @@ fn rebuild(prefs &pref.Preferences) {
|
|||||||
.interpret {
|
.interpret {
|
||||||
util.launch_tool(prefs.is_verbose, 'builders/interpret_builder', os.args[1..])
|
util.launch_tool(prefs.is_verbose, 'builders/interpret_builder', os.args[1..])
|
||||||
}
|
}
|
||||||
.golang {
|
.@go {
|
||||||
println('using Go WIP backend...')
|
println('using Go WIP backend...')
|
||||||
util.launch_tool(prefs.is_verbose, 'builders/golang_builder', os.args[1..])
|
util.launch_tool(prefs.is_verbose, 'builders/go_builder', os.args[1..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
vlib/builtin/go/builtin.go.v
Normal file
5
vlib/builtin/go/builtin.go.v
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module builtin
|
||||||
|
|
||||||
|
pub fn println(s string) {
|
||||||
|
#fmt.Println(s.str)
|
||||||
|
}
|
@ -523,7 +523,7 @@ pub:
|
|||||||
method_idx int
|
method_idx int
|
||||||
rec_mut bool // is receiver mutable
|
rec_mut bool // is receiver mutable
|
||||||
rec_share ShareType
|
rec_share ShareType
|
||||||
language Language // V, C, JS
|
language Language // V, C, JS, Go
|
||||||
file_mode Language // whether *the file*, where a function was a '.c.v', '.js.v' etc.
|
file_mode Language // whether *the file*, where a function was a '.c.v', '.js.v' etc.
|
||||||
no_body bool // just a definition `fn C.malloc()`
|
no_body bool // just a definition `fn C.malloc()`
|
||||||
is_builtin bool // this function is defined in builtin/strconv
|
is_builtin bool // this function is defined in builtin/strconv
|
||||||
|
@ -35,6 +35,7 @@ pub enum Language {
|
|||||||
v
|
v
|
||||||
c
|
c
|
||||||
js
|
js
|
||||||
|
@go
|
||||||
amd64 // aka x86_64
|
amd64 // aka x86_64
|
||||||
i386
|
i386
|
||||||
arm64 // 64-bit arm
|
arm64 // 64-bit arm
|
||||||
|
@ -523,7 +523,8 @@ pub fn (mut v Builder) cc() {
|
|||||||
// whether to just create a .c or .js file and exit, for example: `v -o v.c cmd.v`
|
// whether to just create a .c or .js file and exit, for example: `v -o v.c cmd.v`
|
||||||
ends_with_c := v.pref.out_name.ends_with('.c')
|
ends_with_c := v.pref.out_name.ends_with('.c')
|
||||||
ends_with_js := v.pref.out_name.ends_with('.js')
|
ends_with_js := v.pref.out_name.ends_with('.js')
|
||||||
if ends_with_c || ends_with_js {
|
ends_with_go := v.pref.out_name.ends_with('.go')
|
||||||
|
if ends_with_c || ends_with_js || ends_with_go {
|
||||||
v.pref.skip_running = true
|
v.pref.skip_running = true
|
||||||
msg_mv := 'os.mv_by_cp $v.out_name_c => $v.pref.out_name'
|
msg_mv := 'os.mv_by_cp $v.out_name_c => $v.pref.out_name'
|
||||||
util.timing_start(msg_mv)
|
util.timing_start(msg_mv)
|
||||||
|
@ -88,7 +88,7 @@ fn (mut b Builder) run_compiled_executable_and_exit() {
|
|||||||
os.find_abs_path_of_executable(node_basename) or {
|
os.find_abs_path_of_executable(node_basename) or {
|
||||||
panic('Could not find `$node_basename` in system path. Do you have Node.js installed?')
|
panic('Could not find `$node_basename` in system path. Do you have Node.js installed?')
|
||||||
}
|
}
|
||||||
} else if b.pref.backend == .golang {
|
} else if b.pref.backend == .@go {
|
||||||
go_basename := $if windows { 'go.exe' } $else { 'go' }
|
go_basename := $if windows { 'go.exe' } $else { 'go' }
|
||||||
os.find_abs_path_of_executable(go_basename) or {
|
os.find_abs_path_of_executable(go_basename) or {
|
||||||
panic('Could not find `$go_basename` in system path. Do you have Go installed?')
|
panic('Could not find `$go_basename` in system path. Do you have Go installed?')
|
||||||
@ -99,7 +99,7 @@ fn (mut b Builder) run_compiled_executable_and_exit() {
|
|||||||
mut run_args := []string{cap: b.pref.run_args.len + 1}
|
mut run_args := []string{cap: b.pref.run_args.len + 1}
|
||||||
if b.pref.backend.is_js() {
|
if b.pref.backend.is_js() {
|
||||||
run_args << compiled_file
|
run_args << compiled_file
|
||||||
} else if b.pref.backend == .golang {
|
} else if b.pref.backend == .@go {
|
||||||
run_args << ['run', compiled_file]
|
run_args << ['run', compiled_file]
|
||||||
}
|
}
|
||||||
run_args << b.pref.run_args
|
run_args << b.pref.run_args
|
||||||
@ -195,6 +195,9 @@ pub fn (v Builder) get_builtin_files() []string {
|
|||||||
if v.pref.backend.is_js() {
|
if v.pref.backend.is_js() {
|
||||||
builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin',
|
builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin',
|
||||||
'js'))
|
'js'))
|
||||||
|
} else if v.pref.backend == .@go {
|
||||||
|
builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin',
|
||||||
|
'go'))
|
||||||
} else {
|
} else {
|
||||||
builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin'))
|
builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin'))
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module golangbuilder
|
module gobuilder
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import v.pref
|
import v.pref
|
||||||
@ -9,17 +9,25 @@ import v.gen.golang
|
|||||||
pub fn start() {
|
pub fn start() {
|
||||||
mut args_and_flags := util.join_env_vflags_and_os_args()[1..]
|
mut args_and_flags := util.join_env_vflags_and_os_args()[1..]
|
||||||
prefs, _ := pref.parse_args([], args_and_flags)
|
prefs, _ := pref.parse_args([], args_and_flags)
|
||||||
builder.compile('build', prefs, compile_golang)
|
builder.compile('build', prefs, compile_go)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_golang(mut b builder.Builder) {
|
pub fn compile_go(mut b builder.Builder) {
|
||||||
// v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare'))
|
mut files := b.get_builtin_files()
|
||||||
files := [b.pref.path]
|
files << b.get_user_files()
|
||||||
b.set_module_lookup_paths()
|
b.set_module_lookup_paths()
|
||||||
build_golang(mut b, files, b.pref.out_name)
|
if b.pref.is_verbose {
|
||||||
|
println('all .v files:')
|
||||||
|
println(files)
|
||||||
|
}
|
||||||
|
mut name := b.pref.out_name
|
||||||
|
if !name.ends_with('.go') {
|
||||||
|
name += '.go'
|
||||||
|
}
|
||||||
|
build_go(mut b, files, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_golang(mut b builder.Builder, v_files []string, out_file string) {
|
pub fn build_go(mut b builder.Builder, v_files []string, out_file string) {
|
||||||
if b.pref.os == .windows {
|
if b.pref.os == .windows {
|
||||||
if !b.pref.is_shared && b.pref.build_mode != .build_module
|
if !b.pref.is_shared && b.pref.build_mode != .build_module
|
||||||
&& !b.pref.out_name.ends_with('.exe') {
|
&& !b.pref.out_name.ends_with('.exe') {
|
@ -1765,14 +1765,14 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
|||||||
if c.ct_cond_stack.len > 0 {
|
if c.ct_cond_stack.len > 0 {
|
||||||
node.ct_conds = c.ct_cond_stack.clone()
|
node.ct_conds = c.ct_cond_stack.clone()
|
||||||
}
|
}
|
||||||
if c.pref.backend.is_js() || c.pref.backend == .golang {
|
if c.pref.backend.is_js() || c.pref.backend == .@go {
|
||||||
// consider the the best way to handle the .go.vv files
|
// consider the the best way to handle the .go.vv files
|
||||||
if !c.file.path.ends_with('.js.v') && !c.file.path.ends_with('.go.v')
|
if !c.file.path.ends_with('.js.v') && !c.file.path.ends_with('.go.v')
|
||||||
&& !c.file.path.ends_with('.go.vv') {
|
&& !c.file.path.ends_with('.go.vv') {
|
||||||
c.error('hash statements are only allowed in backend specific files such "x.js.v" and "x.go.v"',
|
c.error('hash statements are only allowed in backend specific files such "x.js.v" and "x.go.v"',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
if c.mod == 'main' && c.pref.backend != .golang {
|
if c.mod == 'main' && c.pref.backend != .@go {
|
||||||
c.error('hash statements are not allowed in the main module. Place them in a separate module.',
|
c.error('hash statements are not allowed in the main module. Place them in a separate module.',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ pub fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
|
|||||||
|
|
||||||
pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.Type {
|
pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.Type {
|
||||||
fn_name := node.name
|
fn_name := node.name
|
||||||
if fn_name == 'main' {
|
if fn_name == 'main' && node.language != .@go {
|
||||||
c.error('the `main` function cannot be called in the program', node.pos)
|
c.error('the `main` function cannot be called in the program', node.pos)
|
||||||
}
|
}
|
||||||
mut has_generic := false // foo<T>() instead of foo<int>()
|
mut has_generic := false // foo<T>() instead of foo<int>()
|
||||||
@ -1292,8 +1292,9 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||||||
} else {
|
} else {
|
||||||
c.fail_if_unreadable(node.left, left_type, 'receiver')
|
c.fail_if_unreadable(node.left, left_type, 'receiver')
|
||||||
}
|
}
|
||||||
if left_sym.language != .js && (!left_sym.is_builtin() && method.mod != 'builtin')
|
if left_sym.language != .js && left_sym.language != .@go
|
||||||
&& method.language == .v && method.no_body {
|
&& (!left_sym.is_builtin() && method.mod != 'builtin') && method.language == .v
|
||||||
|
&& method.no_body {
|
||||||
c.error('cannot call a method that does not have a body', node.pos)
|
c.error('cannot call a method that does not have a body', node.pos)
|
||||||
}
|
}
|
||||||
if node.concrete_types.len > 0 && method.generic_names.len > 0
|
if node.concrete_types.len > 0 && method.generic_names.len > 0
|
||||||
|
@ -13,6 +13,7 @@ const (
|
|||||||
bs = '\\'
|
bs = '\\'
|
||||||
// when to break a line dependant on penalty
|
// when to break a line dependant on penalty
|
||||||
max_len = [0, 35, 60, 85, 93, 100]
|
max_len = [0, 35, 60, 85, 93, 100]
|
||||||
|
v_builtin_fns = ['println', 'print', 'eprintln', 'eprint', 'exit', 'panic']
|
||||||
)
|
)
|
||||||
|
|
||||||
pub struct Gen {
|
pub struct Gen {
|
||||||
@ -867,6 +868,7 @@ pub fn (mut f Gen) expr_stmt(node ast.ExprStmt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f Gen) enum_decl(node ast.EnumDecl) {
|
pub fn (mut f Gen) enum_decl(node ast.EnumDecl) {
|
||||||
|
// TODO(hunam6): transform to custom type + iota
|
||||||
f.attrs(node.attrs)
|
f.attrs(node.attrs)
|
||||||
if node.is_pub {
|
if node.is_pub {
|
||||||
f.write('pub ')
|
f.write('pub ')
|
||||||
@ -889,8 +891,15 @@ pub fn (mut f Gen) enum_decl(node ast.EnumDecl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f Gen) fn_decl(node ast.FnDecl) {
|
pub fn (mut f Gen) fn_decl(node ast.FnDecl) {
|
||||||
f.attrs(node.attrs)
|
v_fn_signature := node.stringify(f.table, f.cur_mod, f.mod2alias)
|
||||||
f.write(node.stringify(f.table, f.cur_mod, f.mod2alias).replace('fn ', 'func '))
|
before_name_idx := v_fn_signature.index('fn') or { 0 } + 3 // will never equal 0
|
||||||
|
after_name_idx := v_fn_signature.index('(') or { 0 } // will never equal 0
|
||||||
|
mut name := v_fn_signature[before_name_idx..after_name_idx]
|
||||||
|
if v_fn_signature[..3] == 'pub' && name !in golang.v_builtin_fns {
|
||||||
|
name = name.capitalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
f.write('func $name${v_fn_signature[after_name_idx..]}')
|
||||||
f.fn_body(node)
|
f.fn_body(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1124,6 +1133,7 @@ pub fn (mut f Gen) interface_method(method ast.FnDecl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f Gen) module_stmt(mod ast.Module) {
|
pub fn (mut f Gen) module_stmt(mod ast.Module) {
|
||||||
|
dump(mod)
|
||||||
f.set_current_module_name(mod.name)
|
f.set_current_module_name(mod.name)
|
||||||
if mod.is_skipped {
|
if mod.is_skipped {
|
||||||
return
|
return
|
||||||
|
@ -203,6 +203,9 @@ pub fn (mut p Parser) set_path(path string) {
|
|||||||
'js' {
|
'js' {
|
||||||
p.file_backend_mode = .js
|
p.file_backend_mode = .js
|
||||||
}
|
}
|
||||||
|
'go' {
|
||||||
|
p.file_backend_mode = .@go
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
arch := pref.arch_from_string(actual_language) or { pref.Arch._auto }
|
arch := pref.arch_from_string(actual_language) or { pref.Arch._auto }
|
||||||
p.file_backend_mode = ast.pref_arch_to_table_language(arch)
|
p.file_backend_mode = ast.pref_arch_to_table_language(arch)
|
||||||
@ -3096,7 +3099,7 @@ fn (mut p Parser) module_decl() ast.Module {
|
|||||||
mut module_pos := token.Pos{}
|
mut module_pos := token.Pos{}
|
||||||
mut name_pos := token.Pos{}
|
mut name_pos := token.Pos{}
|
||||||
mut mod_node := ast.Module{}
|
mut mod_node := ast.Module{}
|
||||||
is_skipped := p.tok.kind != .key_module
|
mut is_skipped := p.tok.kind != .key_module
|
||||||
if is_skipped {
|
if is_skipped {
|
||||||
// the attributes were for something else != module, like a struct/fn/type etc.
|
// the attributes were for something else != module, like a struct/fn/type etc.
|
||||||
module_attrs = []
|
module_attrs = []
|
||||||
@ -3133,6 +3136,13 @@ fn (mut p Parser) module_decl() ast.Module {
|
|||||||
full_name := util.qualify_module(p.pref, name, p.file_name)
|
full_name := util.qualify_module(p.pref, name, p.file_name)
|
||||||
p.mod = full_name
|
p.mod = full_name
|
||||||
p.builtin_mod = p.mod == 'builtin'
|
p.builtin_mod = p.mod == 'builtin'
|
||||||
|
dump(p.builtin_mod)
|
||||||
|
dump(p.file_backend_mode)
|
||||||
|
dump(p.language)
|
||||||
|
// NOTE: Not so sure about that
|
||||||
|
if p.builtin_mod && p.file_backend_mode == .@go {
|
||||||
|
is_skipped = true
|
||||||
|
}
|
||||||
mod_node = ast.Module{
|
mod_node = ast.Module{
|
||||||
name: full_name
|
name: full_name
|
||||||
short_name: name
|
short_name: name
|
||||||
|
@ -51,7 +51,7 @@ pub enum Backend {
|
|||||||
js_freestanding // The JavaScript freestanding backend
|
js_freestanding // The JavaScript freestanding backend
|
||||||
native // The Native backend
|
native // The Native backend
|
||||||
interpret // Interpret the ast
|
interpret // Interpret the ast
|
||||||
golang // Go backend
|
@go // Go backend
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (b Backend) is_js() bool {
|
pub fn (b Backend) is_js() bool {
|
||||||
@ -922,7 +922,7 @@ pub fn backend_from_string(s string) ?Backend {
|
|||||||
match s {
|
match s {
|
||||||
'c' { return .c }
|
'c' { return .c }
|
||||||
'js' { return .js_node }
|
'js' { return .js_node }
|
||||||
'go' { return .golang }
|
'go' { return .@go }
|
||||||
'js_node' { return .js_node }
|
'js_node' { return .js_node }
|
||||||
'js_browser' { return .js_browser }
|
'js_browser' { return .js_browser }
|
||||||
'js_freestanding' { return .js_freestanding }
|
'js_freestanding' { return .js_freestanding }
|
||||||
|
Loading…
Reference in New Issue
Block a user