Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go: preliminary support for builtin functions, various fixes, various tweaks #14908

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cmd/tools/builders/go_builder.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module main

import v.builder.gobuilder

fn main() {
gobuilder.start()
}
7 changes: 0 additions & 7 deletions cmd/tools/builders/golang_builder.v

This file was deleted.

2 changes: 1 addition & 1 deletion cmd/v/v.v
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ fn rebuild(prefs &pref.Preferences) {
}
.golang {
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 changes: 5 additions & 0 deletions vlib/builtin/go/builtin.go.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module builtin

pub fn println(s string) {
#fmt.Println(s.str)
}
2 changes: 1 addition & 1 deletion vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ pub:
method_idx int
rec_mut bool // is receiver mutable
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.
no_body bool // just a definition `fn C.malloc()`
is_builtin bool // this function is defined in builtin/strconv
Expand Down
1 change: 1 addition & 0 deletions vlib/v/ast/types.v
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum Language {
v
c
js
golang
amd64 // aka x86_64
i386
arm64 // 64-bit arm
Expand Down
3 changes: 2 additions & 1 deletion vlib/v/builder/cc.v
Original file line number Diff line number Diff line change
Expand Up @@ -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`
ends_with_c := v.pref.out_name.ends_with('.c')
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
msg_mv := 'os.mv_by_cp $v.out_name_c => $v.pref.out_name'
util.timing_start(msg_mv)
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/builder/compile.v
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ pub fn (v Builder) get_builtin_files() []string {
if v.pref.backend.is_js() {
builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin',
'js'))
} else if v.pref.backend == .golang {
builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin',
'go'))
} else {
builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin'))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module golangbuilder
module gobuilder

import os
import v.pref
Expand All @@ -9,17 +9,25 @@ import v.gen.golang
pub fn start() {
mut args_and_flags := util.join_env_vflags_and_os_args()[1..]
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) {
// v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare'))
files := [b.pref.path]
pub fn compile_go(mut b builder.Builder) {
mut files := b.get_builtin_files()
files << b.get_user_files()
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.is_shared && b.pref.build_mode != .build_module
&& !b.pref.out_name.ends_with('.exe') {
Expand Down
7 changes: 4 additions & 3 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
fn_name := node.name
if fn_name == 'main' {
if fn_name == 'main' && node.language != .golang {
c.error('the `main` function cannot be called in the program', node.pos)
}
mut has_generic := false // foo<T>() instead of foo<int>()
Expand Down Expand Up @@ -1292,8 +1292,9 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
} else {
c.fail_if_unreadable(node.left, left_type, 'receiver')
}
if left_sym.language != .js && (!left_sym.is_builtin() && method.mod != 'builtin')
&& method.language == .v && method.no_body {
if left_sym.language != .js && left_sym.language != .golang
&& (!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)
}
if node.concrete_types.len > 0 && method.generic_names.len > 0
Expand Down
18 changes: 14 additions & 4 deletions vlib/v/gen/golang/golang.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import v.pref
import os

const (
bs = '\\'
bs = '\\'
// 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 {
Expand Down Expand Up @@ -867,6 +868,7 @@ pub fn (mut f Gen) expr_stmt(node ast.ExprStmt) {
}

pub fn (mut f Gen) enum_decl(node ast.EnumDecl) {
// TODO(hunam6): transform to custom type + iota
f.attrs(node.attrs)
if node.is_pub {
f.write('pub ')
Expand All @@ -889,8 +891,15 @@ pub fn (mut f Gen) enum_decl(node ast.EnumDecl) {
}

pub fn (mut f Gen) fn_decl(node ast.FnDecl) {
f.attrs(node.attrs)
f.write(node.stringify(f.table, f.cur_mod, f.mod2alias).replace('fn ', 'func '))
v_fn_signature := node.stringify(f.table, f.cur_mod, f.mod2alias)
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)
}

Expand Down Expand Up @@ -1124,6 +1133,7 @@ pub fn (mut f Gen) interface_method(method ast.FnDecl) {
}

pub fn (mut f Gen) module_stmt(mod ast.Module) {
dump(mod)
f.set_current_module_name(mod.name)
if mod.is_skipped {
return
Expand Down
9 changes: 8 additions & 1 deletion vlib/v/parser/parser.v
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ pub fn (mut p Parser) set_path(path string) {
'js' {
p.file_backend_mode = .js
}
'go' {
p.file_backend_mode = .golang
}
else {
arch := pref.arch_from_string(actual_language) or { pref.Arch._auto }
p.file_backend_mode = ast.pref_arch_to_table_language(arch)
Expand Down Expand Up @@ -3096,7 +3099,7 @@ fn (mut p Parser) module_decl() ast.Module {
mut module_pos := token.Pos{}
mut name_pos := token.Pos{}
mut mod_node := ast.Module{}
is_skipped := p.tok.kind != .key_module
mut is_skipped := p.tok.kind != .key_module
if is_skipped {
// the attributes were for something else != module, like a struct/fn/type etc.
module_attrs = []
Expand Down Expand Up @@ -3133,6 +3136,10 @@ fn (mut p Parser) module_decl() ast.Module {
full_name := util.qualify_module(p.pref, name, p.file_name)
p.mod = full_name
p.builtin_mod = p.mod == 'builtin'
// NOTE: Not so sure about that
if p.builtin_mod && p.file_backend_mode == .golang {
is_skipped = true
}
mod_node = ast.Module{
name: full_name
short_name: name
Expand Down
Loading