From f241945d70707891ee66ec1c16e35ef0c8de33e8 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Fri, 7 Feb 2020 09:19:45 +0100 Subject: [PATCH] v2: `as` cast --- vlib/builtin/array.v | 4 +++- vlib/compiler/expression.v | 25 ++++++++++++++++++++++++- vlib/v/checker/checker.v | 9 +++++++++ vlib/v/parser/parser.v | 4 ++++ vlib/v/token/token.v | 6 ++++-- 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 354b149a34..2102c348c3 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -367,9 +367,11 @@ pub fn (b []byte) hex() string { mut hex := malloc(b.len * 2 + 1) mut ptr := &hex[0] for i := 0; i < b.len; i++ { + // QTODO ptr += C.sprintf(ptr as charptr, '%02x', b[i]) } - return string(hex) + return hex as string + //return string(hex) } // copy copies the `src` byte array elements to the `dst` byte array. diff --git a/vlib/compiler/expression.v b/vlib/compiler/expression.v index 20c48a9be8..d83fbe16f2 100644 --- a/vlib/compiler/expression.v +++ b/vlib/compiler/expression.v @@ -84,6 +84,8 @@ fn (p mut Parser) bool_expression() string { if typ == cast_typ { p.warn('casting `$typ` to `$cast_typ` is not needed') } + is_byteptr := typ == 'byte*' || typ == 'byteptr' + is_bytearr := typ == 'array_byte' if typ in p.table.sum_types { T := p.table.find_type(cast_typ) if T.parent != typ { @@ -104,7 +106,28 @@ exit(1); ') */ - } else { + } else if cast_typ == 'string' { + if is_byteptr || is_bytearr { + if p.tok == .comma { + p.check(.comma) + p.cgen.set_placeholder(start_ph, 'tos((byte *)') + if is_bytearr { + p.gen('.data') + } + p.gen(', ') + p.check_types(p.expression(), 'int') + } + else { + if is_bytearr { + p.gen('.data') + } + p.cgen.set_placeholder(start_ph, '/*!!!*/tos2((byte *)') + p.gen(')') + } + } + } + else { + p.cgen.set_placeholder(start_ph, '($cast_typ)(') p.gen(')') } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c68745f30e..4ea7642968 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -46,6 +46,7 @@ fn (c mut Checker) resolve_types() { } // update any types with unresolved sub types for idx, t in c.table.types { + println('Resolve type: $t.name') if t.kind == .array { mut info := t.array_info() if info.elem_type.typ.kind == .unresolved { @@ -167,6 +168,14 @@ pub fn (c &Checker) check_method_call_expr(method_call_expr ast.MethodCallExpr) if method := typ.typ.find_method(method_call_expr.name) { return method.return_type } + if typ.typ.kind == .array { + a := c.table.find_type('array') or { + exit(1) + } + if method := a.find_method(method_call_expr.name) { + return method.return_type + } + } c.error('type `$typ.typ.name` has no method `$method_call_expr.name`', method_call_expr.pos) exit(1) } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ed4863d440..d4f20763f5 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -579,6 +579,10 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.TypeRef) { else if p.tok.kind == .lsbr { node = p.index_expr(node) // , typ) } + else if p.tok.kind == .key_as { + p.next() + typ = p.parse_type() + } else if p.tok.kind.is_infix() { node,typ = p.infix_expr(node) } diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index 651047a369..986f5f70b4 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -393,7 +393,7 @@ pub fn (tok Token) precedence() int { .left_shift_assign, .righ_shift_assign, .mult_assign { return 2 } - .key_in { + .key_in, .key_as { return 1 } // /.plus_assign { @@ -464,7 +464,9 @@ pub fn (tok Kind) is_relational() bool { } pub fn (kind Kind) is_infix() bool { - return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in, .ge, .le, .logical_or, + return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in, + // + .key_as, .ge, .le, .logical_or, // .and, .dot, .pipe, .amp, .left_shift, .right_shift] }