jsgen: start implementing remaining `expr`s and `stmt`s
parent
fd4d28b7b6
commit
4189190bb8
|
@ -4,7 +4,6 @@ import strings
|
||||||
import v.ast
|
import v.ast
|
||||||
import v.table
|
import v.table
|
||||||
import v.pref
|
import v.pref
|
||||||
import term
|
|
||||||
import v.util
|
import v.util
|
||||||
import v.depgraph
|
import v.depgraph
|
||||||
|
|
||||||
|
@ -193,7 +192,6 @@ pub fn (g JsGen) hashes() string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// V type to JS type
|
// V type to JS type
|
||||||
pub fn (mut g JsGen) typ(t table.Type) string {
|
pub fn (mut g JsGen) typ(t table.Type) string {
|
||||||
sym := g.table.get_type_symbol(t)
|
sym := g.table.get_type_symbol(t)
|
||||||
|
@ -382,9 +380,6 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||||
g.stmt_start_pos = g.out.len
|
g.stmt_start_pos = g.out.len
|
||||||
|
|
||||||
match node {
|
match node {
|
||||||
ast.Module {
|
|
||||||
// TODO: Implement namespaces
|
|
||||||
}
|
|
||||||
ast.AssertStmt {
|
ast.AssertStmt {
|
||||||
g.gen_assert_stmt(it)
|
g.gen_assert_stmt(it)
|
||||||
}
|
}
|
||||||
|
@ -401,12 +396,15 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||||
ast.BranchStmt {
|
ast.BranchStmt {
|
||||||
g.gen_branch_stmt(it)
|
g.gen_branch_stmt(it)
|
||||||
}
|
}
|
||||||
ast.ConstDecl {
|
ast.Comment {
|
||||||
g.gen_const_decl(it)
|
// Skip: don't generate comments
|
||||||
}
|
}
|
||||||
ast.CompIf {
|
ast.CompIf {
|
||||||
// skip: JS has no compile time if
|
// skip: JS has no compile time if
|
||||||
}
|
}
|
||||||
|
ast.ConstDecl {
|
||||||
|
g.gen_const_decl(it)
|
||||||
|
}
|
||||||
ast.DeferStmt {
|
ast.DeferStmt {
|
||||||
g.defer_stmts << *it
|
g.defer_stmts << *it
|
||||||
}
|
}
|
||||||
|
@ -434,6 +432,9 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||||
g.gen_for_stmt(it)
|
g.gen_for_stmt(it)
|
||||||
g.writeln('')
|
g.writeln('')
|
||||||
}
|
}
|
||||||
|
ast.GlobalDecl {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
ast.GoStmt {
|
ast.GoStmt {
|
||||||
g.gen_go_stmt(it)
|
g.gen_go_stmt(it)
|
||||||
g.writeln('')
|
g.writeln('')
|
||||||
|
@ -453,6 +454,9 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||||
ast.InterfaceDecl {
|
ast.InterfaceDecl {
|
||||||
// TODO skip: interfaces not implemented yet
|
// TODO skip: interfaces not implemented yet
|
||||||
}
|
}
|
||||||
|
ast.Module {
|
||||||
|
// skip: namespacing implemented externally
|
||||||
|
}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
if g.defer_stmts.len > 0 {
|
if g.defer_stmts.len > 0 {
|
||||||
g.gen_defer_stmts()
|
g.gen_defer_stmts()
|
||||||
|
@ -468,20 +472,32 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||||
ast.UnsafeStmt {
|
ast.UnsafeStmt {
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
else {
|
else {
|
||||||
verror('jsgen.stmt(): bad node ${typeof(node)}')
|
verror('jsgen.stmt(): bad node ${typeof(node)}')
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) expr(node ast.Expr) {
|
fn (mut g JsGen) expr(node ast.Expr) {
|
||||||
match node {
|
match node {
|
||||||
|
ast.AnonFn {
|
||||||
|
g.gen_fn_decl(it.decl)
|
||||||
|
}
|
||||||
ast.ArrayInit {
|
ast.ArrayInit {
|
||||||
g.gen_array_init_expr(it)
|
g.gen_array_init_expr(it)
|
||||||
}
|
}
|
||||||
|
ast.AsCast {
|
||||||
|
// skip: JS has no types, so no need to cast
|
||||||
|
// TODO: Is jsdoc needed here for TS support?
|
||||||
|
}
|
||||||
ast.AssignExpr {
|
ast.AssignExpr {
|
||||||
g.gen_assign_expr(it)
|
g.gen_assign_expr(it)
|
||||||
}
|
}
|
||||||
|
ast.Assoc {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
ast.BoolLiteral {
|
ast.BoolLiteral {
|
||||||
if it.val == true {
|
if it.val == true {
|
||||||
g.write('true')
|
g.write('true')
|
||||||
|
@ -489,11 +505,18 @@ fn (mut g JsGen) expr(node ast.Expr) {
|
||||||
g.write('false')
|
g.write('false')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast.CallExpr {
|
||||||
|
g.gen_call_expr(it)
|
||||||
|
}
|
||||||
|
ast.CastExpr {
|
||||||
|
// skip: JS has no types, so no need to cast
|
||||||
|
// TODO: Check if jsdoc is needed for TS support
|
||||||
|
}
|
||||||
ast.CharLiteral {
|
ast.CharLiteral {
|
||||||
g.write("'$it.val'")
|
g.write("'$it.val'")
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
ast.ConcatExpr {
|
||||||
g.gen_call_expr(it)
|
// TODO
|
||||||
}
|
}
|
||||||
ast.EnumVal {
|
ast.EnumVal {
|
||||||
styp := g.typ(it.typ)
|
styp := g.typ(it.typ)
|
||||||
|
@ -511,123 +534,74 @@ fn (mut g JsGen) expr(node ast.Expr) {
|
||||||
ast.IfGuardExpr {
|
ast.IfGuardExpr {
|
||||||
// TODO no optionals yet
|
// TODO no optionals yet
|
||||||
}
|
}
|
||||||
ast.IntegerLiteral {
|
ast.IndexExpr {
|
||||||
g.write(it.val)
|
g.gen_index_expr(it)
|
||||||
}
|
}
|
||||||
ast.InfixExpr {
|
ast.InfixExpr {
|
||||||
g.expr(it.left)
|
g.gen_infix_expr(it)
|
||||||
|
}
|
||||||
mut op := it.op.str()
|
ast.IntegerLiteral {
|
||||||
// in js == is non-strict & === is strict, always do strict
|
g.write(it.val)
|
||||||
if op == '==' { op = '===' }
|
|
||||||
else if op == '!=' { op = '!==' }
|
|
||||||
|
|
||||||
g.write(' $op ')
|
|
||||||
g.expr(it.right)
|
|
||||||
}
|
}
|
||||||
ast.MapInit {
|
ast.MapInit {
|
||||||
g.gen_map_init_expr(it)
|
g.gen_map_init_expr(it)
|
||||||
}
|
}
|
||||||
/*
|
ast.MatchExpr {
|
||||||
ast.UnaryExpr {
|
// TODO
|
||||||
g.expr(it.left)
|
|
||||||
g.write(' $it.op ')
|
|
||||||
}
|
}
|
||||||
*/
|
ast.None {
|
||||||
|
// TODO
|
||||||
ast.StringLiteral {
|
|
||||||
g.write('"$it.val"')
|
|
||||||
}
|
}
|
||||||
ast.StringInterLiteral {
|
ast.OrExpr {
|
||||||
g.gen_string_inter_literal(it)
|
// TODO
|
||||||
|
}
|
||||||
|
ast.ParExpr {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
ast.PostfixExpr {
|
ast.PostfixExpr {
|
||||||
g.expr(it.expr)
|
g.expr(it.expr)
|
||||||
g.write(it.op.str())
|
g.write(it.op.str())
|
||||||
}
|
}
|
||||||
ast.StructInit {
|
ast.PrefixExpr {
|
||||||
// `user := User{name: 'Bob'}`
|
// TODO
|
||||||
g.gen_struct_init(it)
|
}
|
||||||
|
ast.RangeExpr {
|
||||||
|
// Only used in IndexExpr, requires index type info
|
||||||
}
|
}
|
||||||
ast.SelectorExpr {
|
ast.SelectorExpr {
|
||||||
g.gen_selector_expr(it)
|
g.gen_selector_expr(it)
|
||||||
}
|
}
|
||||||
ast.AnonFn {
|
ast.SizeOf {
|
||||||
g.gen_anon_fn_decl(it)
|
// TODO
|
||||||
}
|
}
|
||||||
|
ast.StringInterLiteral {
|
||||||
|
g.gen_string_inter_literal(it)
|
||||||
|
}
|
||||||
|
ast.StringLiteral {
|
||||||
|
g.write('"$it.val"')
|
||||||
|
}
|
||||||
|
ast.StructInit {
|
||||||
|
// `user := User{name: 'Bob'}`
|
||||||
|
g.gen_struct_init(it)
|
||||||
|
}
|
||||||
|
ast.Type {
|
||||||
|
// skip: JS has no types
|
||||||
|
// TODO maybe?
|
||||||
|
}
|
||||||
|
ast.TypeOf {
|
||||||
|
g.gen_typeof_expr(it)
|
||||||
|
// TODO: Should this print the V type or the JS type?
|
||||||
|
}
|
||||||
|
/*
|
||||||
else {
|
else {
|
||||||
println(term.red('jsgen.expr(): bad node "${typeof(node)}"'))
|
println(term.red('jsgen.expr(): unhandled node "${typeof(node)}"'))
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_string_inter_literal(it ast.StringInterLiteral) {
|
|
||||||
g.write('tos3(`')
|
|
||||||
for i, val in it.vals {
|
|
||||||
escaped_val := val.replace_each(['`', '\`', '\r\n', '\n'])
|
|
||||||
g.write(escaped_val)
|
|
||||||
if i >= it.exprs.len {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
expr := it.exprs[i]
|
|
||||||
sfmt := it.expr_fmts[i]
|
|
||||||
g.write('\${')
|
|
||||||
if sfmt.len > 0 {
|
|
||||||
fspec := sfmt[sfmt.len - 1]
|
|
||||||
if fspec == `s` && it.expr_types[i] == table.string_type {
|
|
||||||
g.expr(expr)
|
|
||||||
g.write('.str')
|
|
||||||
} else {
|
|
||||||
g.expr(expr)
|
|
||||||
}
|
|
||||||
} else if it.expr_types[i] == table.string_type {
|
|
||||||
// `name.str`
|
|
||||||
g.expr(expr)
|
|
||||||
g.write('.str')
|
|
||||||
} else if it.expr_types[i] == table.bool_type {
|
|
||||||
// `expr ? "true" : "false"`
|
|
||||||
g.expr(expr)
|
|
||||||
g.write(' ? "true" : "false"')
|
|
||||||
} else {
|
|
||||||
sym := g.table.get_type_symbol(it.expr_types[i])
|
|
||||||
|
|
||||||
match sym.kind {
|
|
||||||
.struct_ {
|
|
||||||
g.expr(expr)
|
|
||||||
if sym.has_method('str') {
|
|
||||||
g.write('.str()')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
g.expr(expr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.write('}')
|
|
||||||
}
|
|
||||||
g.write('`)')
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g JsGen) gen_import_stmt(it ast.Import) {
|
|
||||||
mut imports := g.namespace_imports[g.namespace]
|
|
||||||
imports[it.mod] = it.alias
|
|
||||||
g.namespace_imports[g.namespace] = imports
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g JsGen) gen_array_init_expr(it ast.ArrayInit) {
|
|
||||||
type_sym := g.table.get_type_symbol(it.typ)
|
|
||||||
if type_sym.kind != .array_fixed {
|
|
||||||
g.write('[')
|
|
||||||
for i, expr in it.exprs {
|
|
||||||
g.expr(expr)
|
|
||||||
if i < it.exprs.len - 1 {
|
|
||||||
g.write(', ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.write(']')
|
|
||||||
} else {}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// TODO
|
||||||
fn (mut g JsGen) gen_assert_stmt(a ast.AssertStmt) {
|
fn (mut g JsGen) gen_assert_stmt(a ast.AssertStmt) {
|
||||||
g.writeln('// assert')
|
g.writeln('// assert')
|
||||||
g.write('if( ')
|
g.write('if( ')
|
||||||
|
@ -713,12 +687,6 @@ fn (mut g JsGen) gen_assign_stmt(it ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_assign_expr(it ast.AssignExpr) {
|
|
||||||
g.expr(it.left)
|
|
||||||
g.write(' $it.op ')
|
|
||||||
g.expr(it.val)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g JsGen) gen_attr(it ast.Attr) {
|
fn (mut g JsGen) gen_attr(it ast.Attr) {
|
||||||
g.writeln('/* [$it.name] */')
|
g.writeln('/* [$it.name] */')
|
||||||
}
|
}
|
||||||
|
@ -807,8 +775,12 @@ fn (mut g JsGen) gen_fn_decl(it ast.FnDecl) {
|
||||||
g.gen_method_decl(it)
|
g.gen_method_decl(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_anon_fn_decl(it ast.AnonFn) {
|
fn fn_has_go(it ast.FnDecl) bool {
|
||||||
g.gen_method_decl(it.decl)
|
mut has_go := false
|
||||||
|
for stmt in it.stmts {
|
||||||
|
if stmt is ast.GoStmt { has_go = true }
|
||||||
|
}
|
||||||
|
return has_go
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
|
fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
|
||||||
|
@ -875,6 +847,23 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
|
||||||
g.fn_decl = 0
|
g.fn_decl = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) fn_args(args []table.Arg, is_variadic bool) {
|
||||||
|
// no_names := args.len > 0 && args[0].name == 'arg_1'
|
||||||
|
for i, arg in args {
|
||||||
|
name := g.js_name(arg.name)
|
||||||
|
is_varg := i == args.len - 1 && is_variadic
|
||||||
|
if is_varg {
|
||||||
|
g.write('...$name')
|
||||||
|
} else {
|
||||||
|
g.write(name)
|
||||||
|
}
|
||||||
|
// if its not the last argument
|
||||||
|
if i < args.len - 1 {
|
||||||
|
g.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_for_c_stmt(it ast.ForCStmt) {
|
fn (mut g JsGen) gen_for_c_stmt(it ast.ForCStmt) {
|
||||||
g.inside_loop = true
|
g.inside_loop = true
|
||||||
g.write('for (')
|
g.write('for (')
|
||||||
|
@ -961,23 +950,6 @@ fn (mut g JsGen) gen_for_stmt(it ast.ForStmt) {
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) fn_args(args []table.Arg, is_variadic bool) {
|
|
||||||
// no_names := args.len > 0 && args[0].name == 'arg_1'
|
|
||||||
for i, arg in args {
|
|
||||||
name := g.js_name(arg.name)
|
|
||||||
is_varg := i == args.len - 1 && is_variadic
|
|
||||||
if is_varg {
|
|
||||||
g.write('...$name')
|
|
||||||
} else {
|
|
||||||
g.write(name)
|
|
||||||
}
|
|
||||||
// if its not the last argument
|
|
||||||
if i < args.len - 1 {
|
|
||||||
g.write(', ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g JsGen) gen_go_stmt(node ast.GoStmt) {
|
fn (mut g JsGen) gen_go_stmt(node ast.GoStmt) {
|
||||||
// x := node.call_expr as ast.CallEpxr // TODO
|
// x := node.call_expr as ast.CallEpxr // TODO
|
||||||
match node.call_expr {
|
match node.call_expr {
|
||||||
|
@ -1005,39 +977,21 @@ fn (mut g JsGen) gen_go_stmt(node ast.GoStmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) {
|
fn (mut g JsGen) gen_import_stmt(it ast.Import) {
|
||||||
// key_typ_sym := g.table.get_type_symbol(it.key_type)
|
mut imports := g.namespace_imports[g.namespace]
|
||||||
// value_typ_sym := g.table.get_type_symbol(it.value_type)
|
imports[it.mod] = it.alias
|
||||||
// key_typ_str := key_typ_sym.name.replace('.', '__')
|
g.namespace_imports[g.namespace] = imports
|
||||||
// value_typ_str := value_typ_sym.name.replace('.', '__')
|
|
||||||
if it.vals.len > 0 {
|
|
||||||
g.writeln('new Map([')
|
|
||||||
g.inc_indent()
|
|
||||||
for i, key in it.keys {
|
|
||||||
val := it.vals[i]
|
|
||||||
g.write('[')
|
|
||||||
g.expr(key)
|
|
||||||
g.write(', ')
|
|
||||||
g.expr(val)
|
|
||||||
g.write(']')
|
|
||||||
if i < it.keys.len - 1 {
|
|
||||||
g.write(',')
|
|
||||||
}
|
|
||||||
g.writeln('')
|
|
||||||
}
|
|
||||||
g.dec_indent()
|
|
||||||
g.write('])')
|
|
||||||
} else {
|
|
||||||
g.write('new Map()')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_return_stmt(it ast.Return) {
|
fn (mut g JsGen) gen_return_stmt(it ast.Return) {
|
||||||
g.write('return ')
|
|
||||||
|
|
||||||
if it.exprs.len == 0 {
|
if it.exprs.len == 0 {
|
||||||
// Returns nothing
|
// Returns nothing
|
||||||
} else if it.exprs.len == 1 {
|
g.write('return;')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
g.write('return ')
|
||||||
|
if it.exprs.len == 1 {
|
||||||
g.expr(it.exprs[0])
|
g.expr(it.exprs[0])
|
||||||
} else {
|
} else {
|
||||||
// Multi return
|
// Multi return
|
||||||
|
@ -1053,13 +1007,6 @@ fn (mut g JsGen) gen_return_stmt(it ast.Return) {
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) enum_expr(node ast.Expr) {
|
|
||||||
match node {
|
|
||||||
ast.EnumVal { g.write(it.val) }
|
|
||||||
else { g.expr(node) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g JsGen) gen_struct_decl(node ast.StructDecl) {
|
fn (mut g JsGen) gen_struct_decl(node ast.StructDecl) {
|
||||||
g.writeln(g.doc.gen_fac_fn(node.fields))
|
g.writeln(g.doc.gen_fac_fn(node.fields))
|
||||||
g.write('function ${g.js_name(node.name)}({ ')
|
g.write('function ${g.js_name(node.name)}({ ')
|
||||||
|
@ -1104,37 +1051,24 @@ fn (mut g JsGen) gen_struct_decl(node ast.StructDecl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
|
fn (mut g JsGen) gen_array_init_expr(it ast.ArrayInit) {
|
||||||
type_sym := g.table.get_type_symbol(it.typ)
|
type_sym := g.table.get_type_symbol(it.typ)
|
||||||
name := type_sym.name
|
if type_sym.kind != .array_fixed {
|
||||||
if it.fields.len == 0 {
|
g.write('[')
|
||||||
g.write('new ${g.js_name(name)}({})')
|
for i, expr in it.exprs {
|
||||||
} else {
|
g.expr(expr)
|
||||||
g.writeln('new ${g.js_name(name)}({')
|
if i < it.exprs.len - 1 {
|
||||||
g.inc_indent()
|
|
||||||
for i, field in it.fields {
|
|
||||||
g.write('$field.name: ')
|
|
||||||
g.expr(field.expr)
|
|
||||||
if i < it.fields.len - 1 {
|
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
g.writeln('')
|
|
||||||
}
|
|
||||||
g.dec_indent()
|
|
||||||
g.write('})')
|
|
||||||
}
|
}
|
||||||
|
g.write(']')
|
||||||
|
} else {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_ident(node ast.Ident) {
|
fn (mut g JsGen) gen_assign_expr(it ast.AssignExpr) {
|
||||||
if node.kind == .constant {
|
g.expr(it.left)
|
||||||
// TODO: Handle const namespacing: only consts in the main module are handled rn
|
g.write(' $it.op ')
|
||||||
g.write('_CONSTS.')
|
g.expr(it.val)
|
||||||
}
|
|
||||||
|
|
||||||
name := g.js_name(node.name)
|
|
||||||
// TODO `is`
|
|
||||||
// TODO handle optionals
|
|
||||||
g.write(name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
||||||
|
@ -1163,9 +1097,16 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) {
|
fn (mut g JsGen) gen_ident(node ast.Ident) {
|
||||||
g.expr(it.expr)
|
if node.kind == .constant {
|
||||||
g.write('.$it.field_name')
|
// TODO: Handle const namespacing: only consts in the main module are handled rn
|
||||||
|
g.write('_CONSTS.')
|
||||||
|
}
|
||||||
|
|
||||||
|
name := g.js_name(node.name)
|
||||||
|
// TODO `is`
|
||||||
|
// TODO handle optionals
|
||||||
|
g.write(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_if_expr(node ast.IfExpr) {
|
fn (mut g JsGen) gen_if_expr(node ast.IfExpr) {
|
||||||
|
@ -1223,14 +1164,172 @@ fn (mut g JsGen) gen_if_expr(node ast.IfExpr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verror(s string) {
|
fn (mut g JsGen) gen_index_expr(it ast.IndexExpr) {
|
||||||
util.verror('jsgen error', s)
|
// TODO: Handle splice setting if it's implemented
|
||||||
|
if it.index is ast.RangeExpr {
|
||||||
|
range := it.index as ast.RangeExpr
|
||||||
|
g.expr(it.left)
|
||||||
|
g.write('.slice(')
|
||||||
|
if range.has_low {
|
||||||
|
g.expr(range.low)
|
||||||
|
} else {
|
||||||
|
g.write('0')
|
||||||
|
}
|
||||||
|
g.write(', ')
|
||||||
|
if range.has_high {
|
||||||
|
g.expr(range.high)
|
||||||
|
} else {
|
||||||
|
g.expr(it.left)
|
||||||
|
g.write('.length')
|
||||||
|
}
|
||||||
|
g.write(')')
|
||||||
|
} else {
|
||||||
|
// TODO Does this work in all cases?
|
||||||
|
g.expr(it.left)
|
||||||
|
g.write('[')
|
||||||
|
g.expr(it.index)
|
||||||
|
g.write(']')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_has_go(it ast.FnDecl) bool {
|
fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
||||||
mut has_go := false
|
g.expr(it.left)
|
||||||
for stmt in it.stmts {
|
|
||||||
if stmt is ast.GoStmt { has_go = true }
|
mut op := it.op.str()
|
||||||
}
|
// in js == is non-strict & === is strict, always do strict
|
||||||
return has_go
|
if op == '==' { op = '===' }
|
||||||
|
else if op == '!=' { op = '!==' }
|
||||||
|
|
||||||
|
g.write(' $op ')
|
||||||
|
g.expr(it.right)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) {
|
||||||
|
// key_typ_sym := g.table.get_type_symbol(it.key_type)
|
||||||
|
// value_typ_sym := g.table.get_type_symbol(it.value_type)
|
||||||
|
// key_typ_str := key_typ_sym.name.replace('.', '__')
|
||||||
|
// value_typ_str := value_typ_sym.name.replace('.', '__')
|
||||||
|
if it.vals.len > 0 {
|
||||||
|
g.writeln('new Map([')
|
||||||
|
g.inc_indent()
|
||||||
|
for i, key in it.keys {
|
||||||
|
val := it.vals[i]
|
||||||
|
g.write('[')
|
||||||
|
g.expr(key)
|
||||||
|
g.write(', ')
|
||||||
|
g.expr(val)
|
||||||
|
g.write(']')
|
||||||
|
if i < it.keys.len - 1 {
|
||||||
|
g.write(',')
|
||||||
|
}
|
||||||
|
g.writeln('')
|
||||||
|
}
|
||||||
|
g.dec_indent()
|
||||||
|
g.write('])')
|
||||||
|
} else {
|
||||||
|
g.write('new Map()')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) {
|
||||||
|
g.expr(it.expr)
|
||||||
|
g.write('.$it.field_name')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) gen_string_inter_literal(it ast.StringInterLiteral) {
|
||||||
|
// TODO Implement `tos3`
|
||||||
|
g.write('tos3(`')
|
||||||
|
for i, val in it.vals {
|
||||||
|
escaped_val := val.replace_each(['`', '\`', '\r\n', '\n'])
|
||||||
|
g.write(escaped_val)
|
||||||
|
if i >= it.exprs.len {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
expr := it.exprs[i]
|
||||||
|
sfmt := it.expr_fmts[i]
|
||||||
|
g.write('\${')
|
||||||
|
if sfmt.len > 0 {
|
||||||
|
fspec := sfmt[sfmt.len - 1]
|
||||||
|
if fspec == `s` && it.expr_types[i] == table.string_type {
|
||||||
|
g.expr(expr)
|
||||||
|
g.write('.str')
|
||||||
|
} else {
|
||||||
|
g.expr(expr)
|
||||||
|
}
|
||||||
|
} else if it.expr_types[i] == table.string_type {
|
||||||
|
// `name.str`
|
||||||
|
g.expr(expr)
|
||||||
|
g.write('.str')
|
||||||
|
} else if it.expr_types[i] == table.bool_type {
|
||||||
|
// `expr ? "true" : "false"`
|
||||||
|
g.expr(expr)
|
||||||
|
g.write(' ? "true" : "false"')
|
||||||
|
} else {
|
||||||
|
sym := g.table.get_type_symbol(it.expr_types[i])
|
||||||
|
|
||||||
|
match sym.kind {
|
||||||
|
.struct_ {
|
||||||
|
g.expr(expr)
|
||||||
|
if sym.has_method('str') {
|
||||||
|
g.write('.str()')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.expr(expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.write('}')
|
||||||
|
}
|
||||||
|
g.write('`)')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
|
||||||
|
type_sym := g.table.get_type_symbol(it.typ)
|
||||||
|
name := type_sym.name
|
||||||
|
if it.fields.len == 0 {
|
||||||
|
g.write('new ${g.js_name(name)}({})')
|
||||||
|
} else {
|
||||||
|
g.writeln('new ${g.js_name(name)}({')
|
||||||
|
g.inc_indent()
|
||||||
|
for i, field in it.fields {
|
||||||
|
g.write('$field.name: ')
|
||||||
|
g.expr(field.expr)
|
||||||
|
if i < it.fields.len - 1 {
|
||||||
|
g.write(',')
|
||||||
|
}
|
||||||
|
g.writeln('')
|
||||||
|
}
|
||||||
|
g.dec_indent()
|
||||||
|
g.write('})')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) {
|
||||||
|
sym := g.table.get_type_symbol(it.expr_type)
|
||||||
|
if sym.kind == .sum_type {
|
||||||
|
// TODO: JS sumtypes not implemented yet
|
||||||
|
} else if sym.kind == .array_fixed {
|
||||||
|
fixed_info := sym.info as table.ArrayFixed
|
||||||
|
typ_name := g.table.get_type_name(fixed_info.elem_type)
|
||||||
|
g.write('"[$fixed_info.size]${typ_name}"')
|
||||||
|
} else if sym.kind == .function {
|
||||||
|
info := sym.info as table.FnType
|
||||||
|
fn_info := info.func
|
||||||
|
mut repr := 'fn ('
|
||||||
|
for i, arg in fn_info.args {
|
||||||
|
if i > 0 {
|
||||||
|
repr += ', '
|
||||||
|
}
|
||||||
|
repr += g.table.get_type_name(arg.typ)
|
||||||
|
}
|
||||||
|
repr += ')'
|
||||||
|
if fn_info.return_type != table.void_type {
|
||||||
|
repr += ' ${g.table.get_type_name(fn_info.return_type)}'
|
||||||
|
}
|
||||||
|
g.write('"$repr"')
|
||||||
|
} else {
|
||||||
|
g.write('"${sym.name}"')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
// V_COMMIT_HASH 0de70e8
|
||||||
|
// V_CURRENT_COMMIT_HASH 4271eb4
|
||||||
|
// Generated by the V compiler
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/** @namespace builtin */
|
||||||
|
const builtin = (function () {
|
||||||
|
/**
|
||||||
|
* @param {any} s
|
||||||
|
* @returns {void}
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function println(s) {
|
||||||
|
console.log(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} s
|
||||||
|
* @returns {void}
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function print(s) {
|
||||||
|
process.stdout.write(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* module exports */
|
||||||
|
return {
|
||||||
|
println,
|
||||||
|
print,
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
/** @namespace main */
|
||||||
|
const main = (function () {
|
||||||
|
/**
|
||||||
|
* @param {...number} args
|
||||||
|
* @returns {void}
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function variadic(...args) {
|
||||||
|
builtin.println(args);
|
||||||
|
builtin.println(args[0]);
|
||||||
|
builtin.println(args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function vararg_test() {
|
||||||
|
variadic(1, 2, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* program entry point */
|
||||||
|
(function() {
|
||||||
|
vararg_test();
|
||||||
|
/** @type {string[]} - arr1 */
|
||||||
|
const arr1 = ["Hello", "JS", "Backend"];
|
||||||
|
/** @type {number[]} - arr2 */
|
||||||
|
let arr2 = [1, 2, 3, 4, 5];
|
||||||
|
/** @type {string[]} - slice1 */
|
||||||
|
const slice1 = arr1.slice(1, 3);
|
||||||
|
/** @type {number[]} - slice2 */
|
||||||
|
const slice2 = arr2.slice(0, 3);
|
||||||
|
/** @type {number[]} - slice3 */
|
||||||
|
const slice3 = arr2.slice(3, arr2.length);
|
||||||
|
/** @type {string} - idx1 */
|
||||||
|
const idx1 = slice1[1];
|
||||||
|
arr2[0] = 1;
|
||||||
|
arr2[0 + 1] = 2;
|
||||||
|
builtin.println(arr2);
|
||||||
|
/** @type {string} - slice4 */
|
||||||
|
const slice4 = idx1.slice(0, 4);
|
||||||
|
builtin.println(slice4);
|
||||||
|
/** @type {byte} - idx2 */
|
||||||
|
const idx2 = slice4[0];
|
||||||
|
/** @type {Map<string, string>} - m */
|
||||||
|
let m = new Map();
|
||||||
|
/** @type {string} - key */
|
||||||
|
const key = "key";
|
||||||
|
m[key] = "value";
|
||||||
|
/** @type {string} - val */
|
||||||
|
const val = m["key"];
|
||||||
|
builtin.println(val);
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* module exports */
|
||||||
|
return {};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
fn variadic(args ...int) {
|
||||||
|
println(args)
|
||||||
|
println(args[0])
|
||||||
|
println(args[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vararg_test() {
|
||||||
|
variadic(1, 2, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
vararg_test()
|
||||||
|
|
||||||
|
arr1 := ['Hello', 'JS', 'Backend']
|
||||||
|
mut arr2 := [1, 2, 3, 4, 5]
|
||||||
|
|
||||||
|
// Array slices
|
||||||
|
slice1 := arr1[1..3]
|
||||||
|
slice2 := arr2[..3]
|
||||||
|
slice3 := arr2[3..]
|
||||||
|
|
||||||
|
// Array indexes
|
||||||
|
idx1 := slice1[1]
|
||||||
|
arr2[0] = 1
|
||||||
|
arr2[0 + 1] = 2
|
||||||
|
println(arr2)
|
||||||
|
|
||||||
|
// String slices
|
||||||
|
slice4 := idx1[..4]
|
||||||
|
println(slice4) // 'Back'
|
||||||
|
|
||||||
|
// String indexes
|
||||||
|
idx2 := slice4[0]
|
||||||
|
|
||||||
|
// TODO: This does not work for now
|
||||||
|
// arr2[0..1] = arr2[3..4]
|
||||||
|
// println(arr2)
|
||||||
|
|
||||||
|
|
||||||
|
// Maps
|
||||||
|
mut m := map[string]string
|
||||||
|
key := 'key'
|
||||||
|
m[key] = 'value'
|
||||||
|
val := m['key']
|
||||||
|
println(val)
|
|
@ -1,5 +1,5 @@
|
||||||
// V_COMMIT_HASH 74686d0
|
// V_COMMIT_HASH 0de70e8
|
||||||
// V_CURRENT_COMMIT_HASH 0d3f133
|
// V_CURRENT_COMMIT_HASH 4271eb4
|
||||||
// Generated by the V compiler
|
// Generated by the V compiler
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -11,51 +11,81 @@ const _CONSTS = Object.freeze({
|
||||||
v_super: "amazing keyword"
|
v_super: "amazing keyword"
|
||||||
});
|
});
|
||||||
|
|
||||||
/* namespace: hello */
|
/** @namespace builtin */
|
||||||
|
const builtin = (function () {
|
||||||
|
/**
|
||||||
|
* @param {any} s
|
||||||
|
* @returns {void}
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function println(s) {
|
||||||
|
console.log(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} s
|
||||||
|
* @returns {void}
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function print(s) {
|
||||||
|
process.stdout.write(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* module exports */
|
||||||
|
return {
|
||||||
|
println,
|
||||||
|
print,
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
/** @namespace hello */
|
||||||
const hello = (function () {
|
const hello = (function () {
|
||||||
class A {
|
|
||||||
/**
|
/**
|
||||||
* @param {{foo?: string}} values - values for this class fields
|
* @param {{foo?: string}} values - values for this class fields
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
constructor(values) {
|
function A({ foo = "" }) {
|
||||||
this.foo = values.foo
|
this.foo = foo
|
||||||
}
|
};
|
||||||
|
A.prototype = {
|
||||||
|
/** @type {string} - foo */
|
||||||
|
foo: "",
|
||||||
/**
|
/**
|
||||||
* @param {string} s
|
* @param {string} s
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
* @function
|
||||||
*/
|
*/
|
||||||
update(s) {
|
update(s) {
|
||||||
const a = this;
|
const a = this;
|
||||||
a.foo = s;
|
a.foo = s;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
class B {
|
|
||||||
/**
|
/**
|
||||||
* @param {{}} values - values for this class fields
|
* @param {{}} values - values for this class fields
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
constructor(values) {
|
function B({ }) {
|
||||||
}
|
};
|
||||||
}
|
B.prototype = {
|
||||||
|
};
|
||||||
|
|
||||||
const C = Object.freeze({
|
const C = Object.freeze({
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
* @function
|
||||||
*/
|
*/
|
||||||
function v_debugger() {
|
function v_debugger() {
|
||||||
const v = new B({
|
const v = new B({});
|
||||||
});
|
|
||||||
return "Hello";
|
return "Hello";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
* @function
|
||||||
*/
|
*/
|
||||||
function excited() {
|
function excited() {
|
||||||
return v_debugger() + "!";
|
return v_debugger() + "!";
|
||||||
|
@ -70,31 +100,39 @@ const hello = (function () {
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/* namespace: main */
|
/** @namespace main */
|
||||||
const main = (function (hl) {
|
const main = (function (hl) {
|
||||||
class Foo {
|
|
||||||
/**
|
/**
|
||||||
* @param {{a?: hl["A"]["prototype"]}} values - values for this class fields
|
* @param {{a?: hl["A"]["prototype"]}} values - values for this class fields
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
constructor(values) {
|
function Foo({ a = {} }) {
|
||||||
this.a = values.a
|
this.a = a
|
||||||
}
|
};
|
||||||
}
|
Foo.prototype = {
|
||||||
|
/** @type {hl["A"]["prototype"]} - a */
|
||||||
|
a: {}
|
||||||
|
};
|
||||||
|
|
||||||
class Companies {
|
|
||||||
/**
|
/**
|
||||||
* @param {{google?: number, amazon?: boolean, yahoo?: string}} values - values for this class fields
|
* @param {{google?: number, amazon?: boolean, yahoo?: string}} values - values for this class fields
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
constructor(values) {
|
function Companies({ google = 0, amazon = false, yahoo = "" }) {
|
||||||
this.google = values.google
|
this.google = google
|
||||||
this.amazon = values.amazon
|
this.amazon = amazon
|
||||||
this.yahoo = values.yahoo
|
this.yahoo = yahoo
|
||||||
}
|
};
|
||||||
|
Companies.prototype = {
|
||||||
|
/** @type {number} - google */
|
||||||
|
google: 0,
|
||||||
|
/** @type {boolean} - amazon */
|
||||||
|
amazon: false,
|
||||||
|
/** @type {string} - yahoo */
|
||||||
|
yahoo: "",
|
||||||
/**
|
/**
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
|
* @function
|
||||||
*/
|
*/
|
||||||
method() {
|
method() {
|
||||||
const it = this;
|
const it = this;
|
||||||
|
@ -112,7 +150,7 @@ const main = (function (hl) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const POSITION = Object.freeze({
|
const POSITION = Object.freeze({
|
||||||
go_back: 0,
|
go_back: 0,
|
||||||
|
@ -123,6 +161,7 @@ const main = (function (hl) {
|
||||||
* @param {string} v_extends
|
* @param {string} v_extends
|
||||||
* @param {number} v_instanceof
|
* @param {number} v_instanceof
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
* @function
|
||||||
*/
|
*/
|
||||||
function v_class(v_extends, v_instanceof) {
|
function v_class(v_extends, v_instanceof) {
|
||||||
/** @type {number} - v_delete */
|
/** @type {number} - v_delete */
|
||||||
|
@ -131,22 +170,20 @@ const main = (function (hl) {
|
||||||
|
|
||||||
/* program entry point */
|
/* program entry point */
|
||||||
(async function() {
|
(async function() {
|
||||||
console.log("Hello from V.js!");
|
builtin.println("Hello from V.js!");
|
||||||
/** @type {number} - a */
|
/** @type {number} - a */
|
||||||
let a = 1;
|
let a = 1;
|
||||||
a *= 2;
|
a *= 2;
|
||||||
a += 3;
|
a += 3;
|
||||||
console.log(a, " == 5");
|
builtin.println(a);
|
||||||
const b = new hl.A({
|
const b = new hl.A({});
|
||||||
});
|
|
||||||
b.update("an update");
|
b.update("an update");
|
||||||
console.log(b);
|
builtin.println(b);
|
||||||
const c = new Foo({
|
const c = new Foo({
|
||||||
a: new hl.A({
|
a: new hl.A({})
|
||||||
})
|
|
||||||
});
|
});
|
||||||
c.a.update("another update");
|
c.a.update("another update");
|
||||||
console.log(c);
|
builtin.println(c);
|
||||||
/** @type {string} - v */
|
/** @type {string} - v */
|
||||||
const v = "done";
|
const v = "done";
|
||||||
{
|
{
|
||||||
|
@ -198,11 +235,11 @@ const main = (function (hl) {
|
||||||
|
|
||||||
/** @type {(number: number) => void} - fn_in_var */
|
/** @type {(number: number) => void} - fn_in_var */
|
||||||
const fn_in_var = function (number) {
|
const fn_in_var = function (number) {
|
||||||
console.log(tos3(`number: ${number}`));
|
builtin.println(tos3(`number: ${number}`));
|
||||||
};
|
};
|
||||||
hl.v_debugger();
|
hl.v_debugger();
|
||||||
anon_consumer(hl.excited(), function (message) {
|
anon_consumer(hl.excited(), function (message) {
|
||||||
console.log(message);
|
builtin.println(message);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -210,6 +247,7 @@ const main = (function (hl) {
|
||||||
* @param {string} greeting
|
* @param {string} greeting
|
||||||
* @param {(message: string) => void} anon
|
* @param {(message: string) => void} anon
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
* @function
|
||||||
*/
|
*/
|
||||||
function anon_consumer(greeting, anon) {
|
function anon_consumer(greeting, anon) {
|
||||||
anon(greeting);
|
anon(greeting);
|
||||||
|
@ -219,6 +257,7 @@ const main = (function (hl) {
|
||||||
* @param {number} num
|
* @param {number} num
|
||||||
* @param {string} def
|
* @param {string} def
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
* @function
|
||||||
*/
|
*/
|
||||||
function async(num, def) {
|
function async(num, def) {
|
||||||
}
|
}
|
||||||
|
@ -230,6 +269,7 @@ const main = (function (hl) {
|
||||||
* @param {number} game_on
|
* @param {number} game_on
|
||||||
* @param {...string} dummy
|
* @param {...string} dummy
|
||||||
* @returns {[number, number]}
|
* @returns {[number, number]}
|
||||||
|
* @function
|
||||||
*/
|
*/
|
||||||
function hello(game_on, ...dummy) {
|
function hello(game_on, ...dummy) {
|
||||||
for (let _tmp2 = 0; _tmp2 < dummy.length; ++_tmp2) {
|
for (let _tmp2 = 0; _tmp2 < dummy.length; ++_tmp2) {
|
||||||
|
@ -246,8 +286,7 @@ const main = (function (hl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* module exports */
|
/* module exports */
|
||||||
return {
|
return {};
|
||||||
};
|
|
||||||
})(hello);
|
})(hello);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import hello as hl
|
import hello as hl
|
||||||
|
|
||||||
fn JS.alert(arg string)
|
fn JS.alert(arg string)
|
||||||
fn JS.console.log(arg string)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
i_am_a_const = 21214
|
i_am_a_const = 21214
|
||||||
|
@ -29,20 +28,20 @@ fn class(extends string, instanceof int) {
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
JS.console.log('Hello from V.js!')
|
println('Hello from V.js!')
|
||||||
|
|
||||||
mut a := 1
|
mut a := 1
|
||||||
a *= 2
|
a *= 2
|
||||||
a += 3
|
a += 3
|
||||||
JS.console.log(a, ' == 5') // TODO: Handle string interpolation
|
println(a) // TODO: Handle string interpolation
|
||||||
|
|
||||||
b := hl.A{}
|
b := hl.A{}
|
||||||
b.update('an update')
|
b.update('an update')
|
||||||
JS.console.log(b)
|
println(b)
|
||||||
|
|
||||||
c := Foo{ hl.A{} }
|
c := Foo{ hl.A{} }
|
||||||
c.a.update('another update')
|
c.a.update('another update')
|
||||||
JS.console.log(c)
|
println(c)
|
||||||
|
|
||||||
v := "done"
|
v := "done"
|
||||||
{
|
{
|
||||||
|
@ -81,12 +80,12 @@ fn main() {
|
||||||
go async(0, "hello")
|
go async(0, "hello")
|
||||||
|
|
||||||
fn_in_var := fn (number int) {
|
fn_in_var := fn (number int) {
|
||||||
JS.console.log("number: $number")
|
println("number: $number")
|
||||||
}
|
}
|
||||||
|
|
||||||
hl.debugger()
|
hl.debugger()
|
||||||
anon_consumer(hl.excited(), fn (message string) {
|
anon_consumer(hl.excited(), fn (message string) {
|
||||||
JS.console.log(message)
|
println(message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue