first version where we can actually compile hello world
Signed-off-by: Sarmonsiill <sarmonsiill@tilde.guru>
This commit is contained in:
parent
c6de1ed08c
commit
3bab1dbb4f
|
@ -1,3 +1,7 @@
|
|||
__main,,
|
||||
o'Hello World'
|
||||
__greet;String|phrase,String|name;
|
||||
o''#phrase #name'
|
||||
..
|
||||
|
||||
__main;;
|
||||
::greet;'Hello','david'..
|
||||
..
|
||||
|
|
2
run
2
run
|
@ -1 +1 @@
|
|||
clear && cat examples/hello_world.pte && PTE_DEBUG=true v run src/. examples/hello_world.pte -v
|
||||
clear && cat examples/hello_world.pte && PTE_DEBUG=true $HOME/bin/v run src/. examples/hello_world.pte -v
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
module core
|
||||
|
||||
import os
|
||||
import term
|
||||
import rand
|
||||
|
||||
const debug = os.getenv('PTE_DEBUG')
|
||||
|
||||
pub struct Runtime {
|
||||
pub mut:
|
||||
args []string
|
||||
target_file string
|
||||
file_name string
|
||||
mut:
|
||||
cnt []string
|
||||
objs []Object
|
||||
found_main bool
|
||||
transpiled_code string
|
||||
}
|
||||
|
||||
struct Object {
|
||||
name string
|
||||
mut:
|
||||
body []string
|
||||
args []ArgObj
|
||||
}
|
||||
|
||||
struct ArgObj {
|
||||
name string
|
||||
dft string /* default value of func param */
|
||||
typ string
|
||||
}
|
||||
|
||||
pub fn er(i string) {
|
||||
println(term.bg_red(term.bright_white(i)))
|
||||
}
|
||||
|
||||
pub fn dbg(i string) {
|
||||
if debug == 'true' {
|
||||
println(term.bright_blue(i))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut rn Runtime) run() {
|
||||
rn.parse_file()
|
||||
|
||||
rn.parse_functions()
|
||||
|
||||
if !rn.found_main {
|
||||
er('need to have a function called \'main\' declared')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
mut t := []string{}
|
||||
for obj in rn.objs {
|
||||
t << transpile(obj)
|
||||
}
|
||||
rn.transpiled_code = 'module main'
|
||||
rn.transpiled_code = '$rn.transpiled_code\n${t.join('')}'
|
||||
|
||||
dbg('End object: $rn')
|
||||
|
||||
rn.exec()
|
||||
}
|
||||
|
||||
fn (rn Runtime) exec() {
|
||||
file_name := 'tmp_${rand.uuid_v4()}.v'
|
||||
os.write_file(file_name, rn.transpiled_code) or {
|
||||
er('could not write transpiled file: $err')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
result := os.execute('env v $file_name -o ./${rn.file_name}')
|
||||
dbg('$result')
|
||||
os.rm(file_name) or {
|
||||
er('could not remove $file_name: $err')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut rn Runtime) parse_file() {
|
||||
f := os.read_lines(rn.target_file) or {
|
||||
er('could not read from ${rn.target_file}: $err')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
rn.cnt = f
|
||||
|
||||
dbg('file content: ${f.join_lines()}')
|
||||
}
|
||||
|
||||
fn (mut rn Runtime) parse_functions() {
|
||||
mut inside_scope := false
|
||||
mut last_index_flag := 0
|
||||
mut continous_body := []string{}
|
||||
for line in rn.cnt {
|
||||
/* break scope and bump last_index_flag */
|
||||
if line.starts_with('..') && inside_scope {
|
||||
rn.objs[last_index_flag].body = continous_body
|
||||
continous_body = []string{}
|
||||
inside_scope = false
|
||||
last_index_flag = rn.objs.len
|
||||
dbg('last_index_flag is now set to $last_index_flag')
|
||||
}
|
||||
|
||||
if inside_scope {
|
||||
continous_body << line.trim_space()
|
||||
}
|
||||
|
||||
if line.starts_with('__') {
|
||||
inside_scope = true
|
||||
// extract function name
|
||||
x := line.all_after('__')
|
||||
y := x.all_before(';')
|
||||
dbg('FUNC: $y')
|
||||
|
||||
mut obj := Object{name: y}
|
||||
if y == 'main' {
|
||||
rn.found_main = true
|
||||
}
|
||||
|
||||
// extract arguments
|
||||
z := x.all_after_first(';')
|
||||
c := z.all_before_last(';')
|
||||
a := c.split(',')
|
||||
dbg('args: $a')
|
||||
if a.len > 0 {
|
||||
for l in a {
|
||||
s := l.split('|')
|
||||
if s.len > 1 {
|
||||
obj.args << ArgObj{
|
||||
name: s[1]
|
||||
typ: validate_type(s[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rn.objs << obj
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_type(typ string) string {
|
||||
mut ret := ''
|
||||
match typ {
|
||||
'String' { return 'string' }
|
||||
'Int' { ret = 'i64' }
|
||||
'Bool' { ret = 'bool' }
|
||||
else {
|
||||
er('"$typ" is not a type that Pytte recognizes')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
fn transpile(obj Object) string {
|
||||
mut s := []string{}
|
||||
s << 'fn ${obj.name}('
|
||||
if obj.args.len > 0 {
|
||||
mut p := []string{}
|
||||
for a in obj.args {
|
||||
p << '${a.name} ${a.typ}'
|
||||
}
|
||||
s << p.join(',')
|
||||
}
|
||||
s << ') {'
|
||||
if obj.body.len > 0 {
|
||||
for b in obj.body {
|
||||
s << lex(b)
|
||||
}
|
||||
}
|
||||
s << '}'
|
||||
dbg('code: ${s.join('')}')
|
||||
return s.join('')
|
||||
}
|
||||
|
||||
|
||||
fn lex(row string) string {
|
||||
mut s := ''
|
||||
r := term.bright_yellow('TRANSPILING')
|
||||
dbg('\t\t$r \t$row')
|
||||
match true {
|
||||
row.starts_with("o''") {
|
||||
s = row.replace("o''", "println('")
|
||||
s = s.replace("#", "\$")
|
||||
s = '$s )'
|
||||
return s
|
||||
}
|
||||
row.starts_with('::') {
|
||||
s = row.trim_string_left('::')
|
||||
s = s.replace(';', '(')
|
||||
s = s.replace('..', ')')
|
||||
return s
|
||||
} else {
|
||||
s = ''
|
||||
}
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
25
src/pytte.v
25
src/pytte.v
|
@ -2,43 +2,28 @@ module main
|
|||
|
||||
import os
|
||||
import os.cmdline
|
||||
import term
|
||||
import core
|
||||
|
||||
const lang_name = 'pytte'
|
||||
const lang_vers = 'v0.0.1'
|
||||
const lang_line = '$lang_name ($lang_vers)'
|
||||
const debug = os.getenv('PTE_DEBUG')
|
||||
|
||||
struct Runtime {
|
||||
mut:
|
||||
args []string
|
||||
target_file string
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
mut rn := Runtime{}
|
||||
mut rn := core.Runtime{}
|
||||
|
||||
rn.args = cmdline.only_options(os.args[1..])
|
||||
file_args := cmdline.only_non_options(os.args[1..])
|
||||
|
||||
if file_args.len != 1 {
|
||||
er('$lang_line needs a single target file to run/compile')
|
||||
core.er('$lang_line needs a single target file to run/compile')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
rn.target_file = file_args[0]
|
||||
rn.file_name = file_args[0].all_after_last('/').all_before_last('.')
|
||||
|
||||
dbg('Runtime current state: $rn')
|
||||
rn.run()
|
||||
|
||||
}
|
||||
|
||||
fn er(i string) {
|
||||
println(term.bg_red(term.bright_white(i)))
|
||||
}
|
||||
|
||||
fn dbg(i string) {
|
||||
if debug == 'true' {
|
||||
println(term.bg_cyan(term.bright_black(i)))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue