Skip to content

Commit 41564b3

Browse files
committed
transform project into a CLI, restructure project
Signed-off-by: Hunam <[email protected]>
1 parent 0b6d6e7 commit 41564b3

16 files changed

+175
-95
lines changed

.editorconfig

+1-4
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,5 @@ trim_trailing_whitespace = false
2222
# `too_long_line_length_other = 100`
2323
max_line_length = 100
2424

25-
[*.{txt,out}]
25+
[*.txt]
2626
insert_final_newline = false
27-
28-
[{Makefile,GNUmakefile}]
29-
indent_style = tab

.gitignore

-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +0,0 @@
1-
go2v
2-
go2v.exe
3-
t_go2v
4-
t_go2v.exe

DESIGN.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Go2V
22

3-
Go2V is a CLI utility with a function interface to transpile Go source code into V source code.
3+
Go2V is a CLI utility to transpile Go source code into V source code.
44

55
## Summary / steps
66

@@ -18,4 +18,4 @@ Go2V is a CLI utility with a function interface to transpile Go source code into
1818
- [ ] Adapt Go-ish things to V-ish things
1919
- `ast_constructor.v`
2020
- [ ] Transform the V AST struct into V Code
21-
- `v_file_constructor.v`
21+
- `v_file_constructor.v`

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ Go => V source code translator
44
This project is an attempt to automate conversion of [Go](https://golang.org) source to [V](https://vlang.io/).
55

66
Barely started... more to come.
7+
8+
## Usage
9+
10+
See `v run go2v.v help`

go2v.v

+43-63
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,48 @@
1-
import os
2-
3-
// TODO: add a system with a watcher function to make the tree construction stage concurrent and possibly also to the other stages
1+
module main
42

5-
struct Params {
6-
outputs_file bool
7-
input_str string
8-
input_path string
9-
output_path string = 'out.v'
10-
go_path string = 'go'
11-
}
3+
import os
4+
import cli
5+
import transpiler
126

13-
// TODO TEMP REMOVE
147
fn main() {
15-
go_to_v(Params{
16-
input_path: 'test.go'
17-
// outputs_file: true
18-
}) ?
19-
}
20-
21-
pub fn go_to_v(options Params) ?string {
22-
if !os.exists_in_system_path('go') {
23-
// TODO: better error message
24-
panic("Go is needed by the utility and it isn't installed or not present in your path, get it at https://golang.org or manually specify the path to the go binary by passing the --go-path parameter if using the CLI or the {go_path} parameter in the function call")
25-
}
26-
27-
mut str := ''
28-
mut had_to_create_a_file := false
29-
mut input_path := options.input_path
30-
31-
if options.input_path == '' && options.input_str == '' {
32-
panic('Either the input_path or input_str parameter must be set')
33-
} else if options.input_path != '' && options.input_str != '' {
34-
panic('Only one of the input_path or input_str parameter must be set')
35-
} else if options.input_path != '' {
36-
str = os.read_file(options.input_path) ?
37-
} else {
38-
str = options.input_str
39-
input_path = 'temp'
40-
had_to_create_a_file = true
41-
os.write_file('temp', str) ?
42-
}
43-
44-
os.execute('$options.go_path run ${os.resource_abs_path('/')}/get_ast.go -f $input_path -o $options.output_path')
45-
raw_input := os.read_file(options.output_path) ?
46-
os.rm(options.output_path) ?
47-
if had_to_create_a_file {
48-
os.rm(input_path) ?
49-
}
50-
51-
input := raw_input.runes()
52-
tokens := tokenizer(input)
53-
tree := tree_constructor(tokens)
54-
v_ast := ast_constructor(tree)
55-
v_file := v_file_constructor(v_ast)
56-
57-
if options.outputs_file {
58-
os.write_file(options.output_path, v_file) ?
8+
mut app := cli.Command{
9+
name: 'go2v'
10+
description: 'Go2V is a CLI utility to transpile Go source code into V source code.'
11+
execute: fn (cmd cli.Command) ? {
12+
if cmd.args.len == 0 { println('Wrong usage, see "go2v help"') } else { transpiler.go_to_v(cmd.args[0], cmd.args[2] or {
13+
''}) ? }
14+
return
15+
}
16+
commands: [
17+
cli.Command{
18+
name: 'help'
19+
execute: fn (cmd cli.Command) ? {
20+
help_topic := cmd.args[0] or { 'help' }
21+
println(os.read_file(os.resource_abs_path('/help/${help_topic}.txt')) or {
22+
'No help topic for $help_topic'
23+
})
24+
return
25+
}
26+
},
27+
cli.Command{
28+
name: 'test'
29+
execute: fn (cmd cli.Command) ? {
30+
mut stats := ''
31+
if cmd.args.len == 0 {
32+
stats = '-stats'
33+
} else if cmd.args[0] == '-compact' {
34+
stats = ''
35+
} else {
36+
println('Wrong usage, see "go2v help test"')
37+
return
38+
}
39+
40+
os.execvp('${@VEXE}', [stats, 'test', os.resource_abs_path('/tests')]) ?
41+
return
42+
}
43+
},
44+
]
5945
}
60-
61-
// TODO TEMP REMOVE
62-
os.mkdir('test') or {}
63-
os.write_file('test/tree', tree.str()) ?
64-
os.write_file('test/ast', v_ast.str()) ?
65-
os.write_file('test/file.v', v_file) ?
66-
67-
return v_file
46+
app.setup()
47+
app.parse(os.args)
6848
}

help/help.txt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Go2V is a CLI utility to transpile Go source code into V source code.
2+
3+
Usage:
4+
go2v [options] [command] [arguments]
5+
6+
Go must be in path.
7+
8+
Examples:
9+
v hello.go Transpile the file `hello.go` and output it as `hello.v`.
10+
v some_dir -o out_dir (WIP) Transpile all files in the directory `some_dir` and output it in `out_dir`.
11+
12+
Go2V supports the following commands:
13+
test Go2V tests itself with its testing suite located in `tests`.
14+
symlink (WIP) Create a symbolic link for Go2V.
15+
16+
Use "go2v help <command>" for more information about a command.

help/test.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Usage:
2+
go2v [option] test
3+
Go2V tests itself with its testing suite located in `tests`.
4+
5+
Options:
6+
-compact - Run tets without the `-stats` option.
File renamed without changes.

test.go tests/test.go

File renamed without changes.

ast_constructor.v transpiler/ast_constructor.v

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
module transpiler
2+
13
import strings
24

35
// TODO: handle comments

get_ast.go transpiler/get_ast.go

+4-22
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,25 @@
11
package main
22

33
import (
4-
"flag"
54
"fmt"
65
"go/parser"
76
"go/token"
87
"io"
9-
"log"
108
"os"
119
"reflect"
1210
)
1311

14-
//TODO: greatly simplify this code, for now I just copied the a piece of code given by *@JalonSolov#0531* on Discord
15-
1612
func main() {
17-
pathname := ""
18-
outpathname := ""
19-
flag.StringVar(&pathname, "f", "", "file to process")
20-
flag.StringVar(&outpathname, "o", "", "file to output")
21-
fmt.Println(pathname)
22-
fmt.Println(outpathname)
23-
24-
flag.Parse()
13+
path := os.Args[1]
2514

2615
fset := token.NewFileSet()
27-
node, err := parser.ParseFile(fset, pathname, nil, parser.ParseComments)
28-
if err != nil {
29-
log.Fatal(err)
30-
}
16+
node, _ := parser.ParseFile(fset, path, nil, parser.ParseComments)
3117

32-
f, err := os.OpenFile(outpathname, os.O_WRONLY|os.O_CREATE, 0600)
33-
if err != nil {
34-
log.Fatal(err)
35-
}
18+
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600)
3619
defer f.Close()
3720

3821
fprint(f, fset, node, NotNilFilter)
39-
//TODO: find if there is a way to just use the built-in ast.Print() function, the only differences are:
22+
//TODO: find if there is a way to just use the built-in ast.Print() function as the only differences are:
4023
/*
4124
FROM ast/print.go:
4225
86
@@ -51,7 +34,6 @@ func main() {
5134
104 - }
5235
105 for j := p.indent; j > 0; j-- {
5336
*/
54-
// Maybe find a way to overwrite the variable `indent` and the function `printer.Write`
5537
}
5638

5739
// A FieldFilter may be provided to Fprint to control the output.

transpiler/go2v.v

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
module transpiler
2+
3+
import os
4+
5+
// TODO: add a system with a watcher function to make the tree construction stage concurrent and possibly also to the other stages
6+
7+
pub struct Params {
8+
outputs_file bool
9+
input_str string
10+
input_path string
11+
output_path string = 'out.v'
12+
go_path string = 'go'
13+
}
14+
15+
pub fn go_to_v(input_path string, output_path string) ? {
16+
mut out_path := output_path
17+
18+
if !os.exists_in_system_path('go') {
19+
panic("Go is needed by the utility and it isn't installed or not present in your path, get it at https://golang.org.")
20+
}
21+
22+
if !os.exists(input_path) {
23+
panic("The input file/directory doesn't exist.")
24+
}
25+
26+
is_dir := os.is_dir(input_path)
27+
28+
// default output directory for directory transpilation
29+
if output_path == '' && is_dir {
30+
out_path = 'out'
31+
}
32+
33+
mut inputs := []string{}
34+
mut files_name := []string{}
35+
if !is_dir {
36+
inputs << os.read_file(input_path) ?
37+
files_name << input_path#[..-3] + '.v'
38+
} else {
39+
for input in os.ls(input_path) or { []string{} } {
40+
if input.ends_with('.go') {
41+
inputs << os.read_file('$os.getwd()/$input_path/$input') ?
42+
files_name << input#[..-3] + '.v'
43+
}
44+
}
45+
}
46+
47+
// custom output file for file transpilation
48+
if out_path != '' && !is_dir {
49+
files_name[0] = out_path
50+
out_path = '.'
51+
}
52+
53+
if !is_dir {
54+
convert_and_write(inputs.first(), files_name.first(), out_path) ?
55+
} else {
56+
os.mkdir(out_path) or {}
57+
for i, input in inputs {
58+
convert_and_write(input, files_name[i], out_path) ?
59+
}
60+
}
61+
}
62+
63+
fn convert_and_write(input string, output_file string, output_path string) ? {
64+
output := '$os.getwd()/$output_path/$output_file'
65+
os.write_file(output, input) ?
66+
os.execute('go run "${os.resource_abs_path('transpiler')}/get_ast.go" "$output"')
67+
68+
raw_input := os.read_file(output) ?
69+
runes_input := raw_input.runes()
70+
tokens := tokenizer(runes_input)
71+
tree := tree_constructor(tokens)
72+
v_ast := ast_constructor(tree)
73+
v_file := v_file_constructor(v_ast)
74+
75+
// TODO TEMP REMOVE
76+
/*
77+
os.mkdir('test') or {}
78+
os.write_file('test/tree', tree.str()) ?
79+
os.write_file('test/ast', v_ast.str()) ?
80+
os.write_file('test/file.v', v_file) ?
81+
*/
82+
83+
os.write_file(output, v_file) ?
84+
}

tokenizer.v transpiler/tokenizer.v

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
module transpiler
2+
13
enum State {
24
tree_name
35
body_name

tree_constructor.v transpiler/tree_constructor.v

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
module transpiler
2+
13
// it's best to use a struct instead of a sumtype because for the ast construction stage it make the code extremly complex to write and read
24
struct Child {
35
mut:

v_file_constructor.v transpiler/v_file_constructor.v

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
module transpiler
2+
13
fn v_file_constructor(v_ast VAST) string {
24
mut v := v_ast
35
v.handle_module()

v.mod

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Module {
2+
name: 'go2v'
3+
description: 'Go2V is a CLI utility to transpile Go source code into V source code.'
4+
version: '0.0.1'
5+
license: 'GPL-2.0'
6+
dependencies: []
7+
}

0 commit comments

Comments
 (0)