2020-02-21 18:13:34 +01:00
|
|
|
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
2020-02-19 16:12:39 +01:00
|
|
|
module ast
|
|
|
|
|
2020-04-07 04:05:59 +02:00
|
|
|
// These methods are used only by vfmt, vdoc, and for debugging.
|
2020-04-16 15:42:40 +02:00
|
|
|
import v.table
|
|
|
|
import strings
|
2020-02-19 16:12:39 +01:00
|
|
|
|
|
|
|
pub fn (node &FnDecl) str(t &table.Table) string {
|
2020-04-21 05:11:50 +02:00
|
|
|
mut f := strings.new_builder(30)
|
2020-02-29 17:51:35 +01:00
|
|
|
if node.is_pub {
|
|
|
|
f.write('pub ')
|
|
|
|
}
|
2020-04-21 05:11:50 +02:00
|
|
|
mut receiver := ''
|
2020-02-19 16:12:39 +01:00
|
|
|
if node.is_method {
|
2020-04-21 05:11:50 +02:00
|
|
|
mut styp := t.type_to_str(node.receiver.typ)
|
|
|
|
mut m := if node.rec_mut { 'mut ' } else { '' }
|
2020-04-09 15:05:06 +02:00
|
|
|
if node.rec_mut {
|
2020-04-21 05:11:50 +02:00
|
|
|
styp = styp[1..] // remove &
|
2020-04-09 15:05:06 +02:00
|
|
|
}
|
2020-04-16 15:42:40 +02:00
|
|
|
receiver = '($m$node.receiver.name $styp) '
|
2020-04-09 15:05:06 +02:00
|
|
|
/*
|
2020-02-19 16:12:39 +01:00
|
|
|
sym := t.get_type_symbol(node.receiver.typ)
|
|
|
|
name := sym.name.after('.')
|
2020-04-07 04:05:59 +02:00
|
|
|
mut m := if node.rec_mut { 'mut ' } else { '' }
|
2020-04-25 09:08:53 +02:00
|
|
|
if !node.rec_mut && node.receiver.typ.is_ptr() {
|
2020-04-07 04:05:59 +02:00
|
|
|
m = '&'
|
|
|
|
}
|
2020-02-29 15:04:07 +01:00
|
|
|
receiver = '($node.receiver.name $m$name) '
|
2020-04-25 20:58:00 +02:00
|
|
|
*/
|
2020-02-19 16:12:39 +01:00
|
|
|
}
|
2020-04-25 17:49:16 +02:00
|
|
|
mut name := if node.is_anon { '' } else { node.name.after('.') }
|
2020-05-19 17:12:47 +02:00
|
|
|
if node.language == .c {
|
2020-04-04 15:36:46 +02:00
|
|
|
name = 'C.$name'
|
|
|
|
}
|
2020-05-19 17:12:47 +02:00
|
|
|
else if node.language == .js {
|
2020-04-15 23:16:49 +02:00
|
|
|
name = 'JS.$name'
|
|
|
|
}
|
2020-05-21 03:58:50 +02:00
|
|
|
f.write('fn ${receiver}${name}')
|
|
|
|
if node.is_generic {
|
|
|
|
f.write('<T>')
|
|
|
|
}
|
|
|
|
f.write('(')
|
2020-02-19 16:12:39 +01:00
|
|
|
for i, arg in node.args {
|
2020-03-11 01:31:24 +01:00
|
|
|
// skip receiver
|
2020-05-06 12:26:00 +02:00
|
|
|
// if (node.is_method || node.is_interface) && i == 0 {
|
2020-03-11 01:31:24 +01:00
|
|
|
if node.is_method && i == 0 {
|
|
|
|
continue
|
|
|
|
}
|
2020-05-06 12:26:00 +02:00
|
|
|
if arg.is_hidden {
|
|
|
|
continue
|
|
|
|
}
|
2020-02-19 16:12:39 +01:00
|
|
|
is_last_arg := i == node.args.len - 1
|
2020-04-09 15:05:06 +02:00
|
|
|
should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ || (node.is_variadic &&
|
|
|
|
i == node.args.len - 2)
|
2020-05-06 12:43:46 +02:00
|
|
|
if arg.is_mut {
|
|
|
|
f.write('mut ')
|
|
|
|
}
|
2020-02-19 16:12:39 +01:00
|
|
|
f.write(arg.name)
|
2020-04-21 05:11:50 +02:00
|
|
|
mut s := t.type_to_str(arg.typ)
|
2020-04-07 15:15:45 +02:00
|
|
|
if arg.is_mut {
|
2020-05-06 12:43:46 +02:00
|
|
|
// f.write(' mut')
|
2020-04-07 15:15:45 +02:00
|
|
|
if s.starts_with('&') {
|
|
|
|
s = s[1..]
|
|
|
|
}
|
|
|
|
}
|
2020-02-19 16:12:39 +01:00
|
|
|
if should_add_type {
|
2020-02-29 15:04:07 +01:00
|
|
|
if node.is_variadic && is_last_arg {
|
2020-04-07 15:15:45 +02:00
|
|
|
f.write(' ...' + s)
|
2020-04-07 04:05:59 +02:00
|
|
|
} else {
|
2020-04-07 15:15:45 +02:00
|
|
|
f.write(' ' + s)
|
2020-02-29 15:04:07 +01:00
|
|
|
}
|
2020-02-19 16:12:39 +01:00
|
|
|
}
|
|
|
|
if !is_last_arg {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.write(')')
|
2020-03-11 16:10:46 +01:00
|
|
|
if node.return_type != table.void_type {
|
2020-02-28 17:21:20 +01:00
|
|
|
// typ := t.type_to_str(node.typ)
|
|
|
|
// if typ.starts_with('
|
2020-03-11 16:10:46 +01:00
|
|
|
f.write(' ' + t.type_to_str(node.return_type))
|
2020-02-19 16:12:39 +01:00
|
|
|
}
|
|
|
|
return f.str()
|
|
|
|
}
|
2020-02-27 21:29:38 +01:00
|
|
|
|
|
|
|
// string representaiton of expr
|
|
|
|
pub fn (x Expr) str() string {
|
|
|
|
match x {
|
2020-04-24 16:04:39 +02:00
|
|
|
BoolLiteral {
|
|
|
|
return it.val.str()
|
2020-03-26 19:17:14 +01:00
|
|
|
}
|
2020-04-24 16:04:39 +02:00
|
|
|
CastExpr {
|
|
|
|
return '${it.typname}(${it.expr.str()})'
|
2020-02-27 21:29:38 +01:00
|
|
|
}
|
2020-04-24 16:04:39 +02:00
|
|
|
CallExpr {
|
|
|
|
sargs := args2str(it.args)
|
|
|
|
if it.is_method {
|
|
|
|
return '${it.left.str()}.${it.name}($sargs)'
|
|
|
|
}
|
|
|
|
return '${it.mod}.${it.name}($sargs)'
|
2020-02-27 21:29:38 +01:00
|
|
|
}
|
2020-04-10 21:00:54 +02:00
|
|
|
CharLiteral {
|
|
|
|
return '`$it.val`'
|
|
|
|
}
|
2020-04-24 16:04:39 +02:00
|
|
|
EnumVal {
|
|
|
|
return '.${it.val}'
|
2020-02-27 21:29:38 +01:00
|
|
|
}
|
2020-04-08 04:47:29 +02:00
|
|
|
FloatLiteral {
|
|
|
|
return it.val
|
|
|
|
}
|
2020-04-24 16:04:39 +02:00
|
|
|
Ident {
|
|
|
|
return it.name
|
|
|
|
}
|
|
|
|
IndexExpr {
|
|
|
|
return '${it.left.str()}[${it.index.str()}]'
|
|
|
|
}
|
|
|
|
IntegerLiteral {
|
|
|
|
return it.val
|
|
|
|
}
|
|
|
|
InfixExpr {
|
|
|
|
return '${it.left.str()} $it.op.str() ${it.right.str()}'
|
|
|
|
}
|
|
|
|
ParExpr {
|
|
|
|
return it.expr.str()
|
|
|
|
}
|
|
|
|
PrefixExpr {
|
|
|
|
return it.op.str() + it.right.str()
|
|
|
|
}
|
|
|
|
SelectorExpr {
|
2020-05-09 15:16:48 +02:00
|
|
|
return '${it.expr.str()}.${it.field_name}'
|
2020-02-27 21:29:38 +01:00
|
|
|
}
|
2020-04-04 23:51:36 +02:00
|
|
|
StringInterLiteral {
|
2020-04-27 22:53:26 +02:00
|
|
|
mut res := []string{}
|
2020-04-04 23:51:36 +02:00
|
|
|
res << "'"
|
|
|
|
for i, val in it.vals {
|
|
|
|
res << val
|
2020-04-07 04:05:59 +02:00
|
|
|
if i >= it.exprs.len {
|
2020-04-04 23:51:36 +02:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
res << '$'
|
|
|
|
if it.expr_fmts[i].len > 0 {
|
|
|
|
res << '{'
|
|
|
|
res << it.exprs[i].str()
|
|
|
|
res << it.expr_fmts[i]
|
|
|
|
res << '}'
|
2020-04-07 04:05:59 +02:00
|
|
|
} else {
|
2020-04-04 23:51:36 +02:00
|
|
|
res << it.exprs[i].str()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
res << "'"
|
|
|
|
return res.join('')
|
|
|
|
}
|
2020-04-24 16:04:39 +02:00
|
|
|
StringLiteral {
|
|
|
|
return '"$it.val"'
|
2020-04-10 21:40:56 +02:00
|
|
|
}
|
2020-04-10 21:52:12 +02:00
|
|
|
TypeOf {
|
|
|
|
return 'typeof(${it.expr.str()})'
|
|
|
|
}
|
2020-02-27 21:29:38 +01:00
|
|
|
else {
|
2020-04-02 21:31:36 +02:00
|
|
|
return '[unhandled expr type ${typeof(x)}]'
|
2020-02-27 21:29:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-09 12:24:13 +02:00
|
|
|
pub fn (a CallArg) str() string {
|
|
|
|
if a.is_mut {
|
|
|
|
return 'mut ${a.expr.str()}'
|
|
|
|
}
|
|
|
|
return '${a.expr.str()}'
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn args2str(args []CallArg) string {
|
2020-04-26 09:17:13 +02:00
|
|
|
mut res := []string{}
|
2020-04-09 12:24:13 +02:00
|
|
|
for a in args {
|
|
|
|
res << a.str()
|
|
|
|
}
|
|
|
|
return res.join(', ')
|
|
|
|
}
|
|
|
|
|
2020-02-27 21:29:38 +01:00
|
|
|
pub fn (node Stmt) str() string {
|
|
|
|
match node {
|
2020-03-10 12:01:37 +01:00
|
|
|
AssignStmt {
|
2020-04-21 05:11:50 +02:00
|
|
|
mut out := ''
|
2020-04-07 04:05:59 +02:00
|
|
|
for i, ident in it.left {
|
2020-03-10 12:01:37 +01:00
|
|
|
var_info := ident.var_info()
|
|
|
|
if var_info.is_mut {
|
|
|
|
out += 'mut '
|
|
|
|
}
|
|
|
|
out += ident.name
|
2020-04-07 04:05:59 +02:00
|
|
|
if i < it.left.len - 1 {
|
2020-03-10 12:01:37 +01:00
|
|
|
out += ','
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out += ' $it.op.str() '
|
2020-04-07 04:05:59 +02:00
|
|
|
for i, val in it.right {
|
2020-03-10 12:01:37 +01:00
|
|
|
out += val.str()
|
2020-04-07 04:05:59 +02:00
|
|
|
if i < it.right.len - 1 {
|
2020-03-10 12:01:37 +01:00
|
|
|
out += ','
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out
|
2020-02-27 21:29:38 +01:00
|
|
|
}
|
|
|
|
ExprStmt {
|
|
|
|
return it.expr.str()
|
|
|
|
}
|
|
|
|
FnDecl {
|
|
|
|
return 'fn ${it.name}() { $it.stmts.len stmts }'
|
|
|
|
}
|
|
|
|
else {
|
2020-04-02 21:31:36 +02:00
|
|
|
return '[unhandled stmt str type: ${typeof(node)} ]'
|
2020-02-27 21:29:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|