From: Jean Privat Date: Sat, 18 Apr 2015 09:47:09 +0000 (+0700) Subject: Merge: Option --keep-going X-Git-Tag: v0.7.4~19 X-Git-Url: http://nitlanguage.org?hp=d869fda0f448fad01d8006bdf82d0315087734cf Merge: Option --keep-going Follow up of #959 and #1241. Now an option is exposed so people can happily try to use it on various tools that will turn them berserk and make them want to kill you. Pull-Request: #1270 Reviewed-by: Alexis Laferrière Reviewed-by: Romain Chanoir --- diff --git a/lib/standard/collection/array.nit b/lib/standard/collection/array.nit index 3cc0b57..cdb5242 100644 --- a/lib/standard/collection/array.nit +++ b/lib/standard/collection/array.nit @@ -147,6 +147,55 @@ abstract class AbstractArrayRead[E] private var free_iterator: nullable ArrayIterator[E] = null redef fun reverse_iterator do return new ArrayReverseIterator[E](self) + + # Returns a sub-array containing `count` elements starting from `from`. + # + # For most cases (see other case bellow), + # the first element is `from` and + # the last element is `from+count-1`. + # + # ~~~ + # var a = [10, 20, 30, 40, 50] + # assert a.sub(0, 3) == [10, 20, 30] + # assert a.sub(3, 2) == [40, 50] + # assert a.sub(3, 1) == [40] + # ~~~ + # + # If `count` is 0 or negative then an empty array is returned + # + # ~~~ + # assert a.sub(3,0).is_empty + # assert a.sub(3,-1).is_empty + # ~~~ + # + # If `from < 0` or `from+count>length` then inexistent elements are ignored. + # In this case the length of the result is lower than count. + # + # ~~~ + # assert a.sub(-2, 4) == [10, 20] + # assert a.sub(4, 99) == [50] + # assert a.sub(-9, 99) == [10,20,30,40,50] + # assert a.sub(-99, 9).is_empty + # ~~~ + fun sub(from: Int, count: Int): Array[E] do + if from < 0 then + count += from + from = 0 + end + if count < 0 then + count = 0 + end + var to = from + count + if to > length then + to = length + end + var res = new Array[E].with_capacity(to - from) + while from < to do + res.add(self[from]) + from += 1 + end + return res + end end # Resizable one dimension array of objects. diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 2359c7d..1b8bf6a 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -1146,40 +1146,43 @@ abstract class AbstractCompilerVisitor # Evaluate `args` as expressions in the call of `mpropdef` on `recv`. # This method is used to manage varargs in signatures and returns the real array # of runtime variables to use in the call. - fun varargize(mpropdef: MMethodDef, recv: RuntimeVariable, args: SequenceRead[AExpr]): Array[RuntimeVariable] + fun varargize(mpropdef: MMethodDef, map: nullable SignatureMap, recv: RuntimeVariable, args: SequenceRead[AExpr]): Array[RuntimeVariable] do var msignature = mpropdef.new_msignature or else mpropdef.msignature.as(not null) var res = new Array[RuntimeVariable] res.add(recv) - if args.is_empty then return res + if msignature.arity == 0 then return res - var vararg_rank = msignature.vararg_rank - var vararg_len = args.length - msignature.arity - if vararg_len < 0 then vararg_len = 0 + if map == null then + assert args.length == msignature.arity + for ne in args do + res.add self.expr(ne, null) + end + return res + end + + # Eval in order of arguments, not parameters + var exprs = new Array[RuntimeVariable].with_capacity(args.length) + for ne in args do + exprs.add self.expr(ne, null) + end + # Fill `res` with the result of the evaluation according to the mapping for i in [0..msignature.arity[ do - if i == vararg_rank then - var ne = args[i] - if ne isa AVarargExpr then - var e = self.expr(ne.n_expr, null) - res.add(e) - continue - end - var vararg = new Array[RuntimeVariable] - for j in [vararg_rank..vararg_rank+vararg_len] do - var e = self.expr(args[j], null) - vararg.add(e) - end - var elttype = msignature.mparameters[vararg_rank].mtype + var param = msignature.mparameters[i] + var j = map.map.get_or_null(i) + if j == null then + continue + end + if param.is_vararg and map.vararg_decl > 0 then + var vararg = exprs.sub(j, map.vararg_decl) + var elttype = param.mtype var arg = self.vararg_instance(mpropdef, recv, vararg, elttype) res.add(arg) - else - var j = i - if i > vararg_rank then j += vararg_len - var e = self.expr(args[j], null) - res.add(e) + continue end + res.add exprs[j] end return res end @@ -2975,7 +2978,7 @@ redef class ASendExpr do var recv = v.expr(self.n_expr, null) var callsite = self.callsite.as(not null) - var args = v.varargize(callsite.mpropdef, recv, self.raw_arguments) + var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments) return v.compile_callsite(callsite, args) end end @@ -2985,7 +2988,7 @@ redef class ASendReassignFormExpr do var recv = v.expr(self.n_expr, null) var callsite = self.callsite.as(not null) - var args = v.varargize(callsite.mpropdef, recv, self.raw_arguments) + var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments) var value = v.expr(self.n_value, null) @@ -3007,26 +3010,33 @@ redef class ASuperExpr var callsite = self.callsite if callsite != null then - var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs) + var args - # Add additional arguments for the super init call - if args.length == 1 then + if self.n_args.n_exprs.is_empty then + # Add automatic arguments for the super init call + args = [recv] for i in [0..callsite.msignature.arity[ do args.add(v.frame.arguments[i+1]) end + else + args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs) end + # Super init call var res = v.compile_callsite(callsite, args) return res end var mpropdef = self.mpropdef.as(not null) - var args = v.varargize(mpropdef, recv, self.n_args.n_exprs) - if args.length == 1 then + + var args + if self.n_args.n_exprs.is_empty then args = v.frame.arguments + else + args = v.varargize(mpropdef, signaturemap, recv, self.n_args.n_exprs) end - # stantard call-next-method + # Standard call-next-method return v.supercall(mpropdef, recv.mtype.as(MClassType), args) end end @@ -3050,7 +3060,7 @@ redef class ANewExpr var callsite = self.callsite if callsite == null then return recv - var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs) + var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs) var res2 = v.compile_callsite(callsite, args) if res2 != null then #self.debug("got {res2} from {mproperty}. drop {recv}") @@ -3102,6 +3112,13 @@ redef class AIssetAttrExpr end end +redef class AVarargExpr + redef fun expr(v) + do + return v.expr(self.n_expr, null) + end +end + redef class ADebugTypeExpr redef fun stmt(v) do diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index 7d7cab9..c1bd59b 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -370,42 +370,48 @@ class NaiveInterpreter # This method is used to manage varargs in signatures and returns the real array # of instances to use in the call. # Return `null` if one of the evaluation of the arguments return null. - fun varargize(mpropdef: MMethodDef, recv: Instance, args: SequenceRead[AExpr]): nullable Array[Instance] + fun varargize(mpropdef: MMethodDef, map: nullable SignatureMap, recv: Instance, args: SequenceRead[AExpr]): nullable Array[Instance] do var msignature = mpropdef.new_msignature or else mpropdef.msignature.as(not null) var res = new Array[Instance] res.add(recv) - if args.is_empty then return res + if msignature.arity == 0 then return res + + if map == null then + assert args.length == msignature.arity else debug("Expected {msignature.arity} args, got {args.length}") + for ne in args do + var e = self.expr(ne) + if e == null then return null + res.add e + end + return res + end + + # Eval in order of arguments, not parameters + var exprs = new Array[Instance].with_capacity(args.length) + for ne in args do + var e = self.expr(ne) + if e == null then return null + exprs.add e + end - var vararg_rank = msignature.vararg_rank - var vararg_len = args.length - msignature.arity - if vararg_len < 0 then vararg_len = 0 + # Fill `res` with the result of the evaluation according to the mapping for i in [0..msignature.arity[ do - if i == vararg_rank then - var ne = args[i] - if ne isa AVarargExpr then - var e = self.expr(ne.n_expr) - if e == null then return null - res.add(e) - continue - end - var vararg = new Array[Instance] - for j in [vararg_rank..vararg_rank+vararg_len] do - var e = self.expr(args[j]) - if e == null then return null - vararg.add(e) - end - var elttype = msignature.mparameters[vararg_rank].mtype.anchor_to(self.mainmodule, recv.mtype.as(MClassType)) - res.add(self.array_instance(vararg, elttype)) - else - var j = i - if i > vararg_rank then j += vararg_len - var e = self.expr(args[j]) - if e == null then return null - res.add(e) + var param = msignature.mparameters[i] + var j = map.map.get_or_null(i) + if j == null then + continue + end + if param.is_vararg and map.vararg_decl > 0 then + var vararg = exprs.sub(j, map.vararg_decl) + var elttype = param.mtype.anchor_to(self.mainmodule, recv.mtype.as(MClassType)) + var arg = self.array_instance(vararg, elttype) + res.add(arg) + continue end + res.add exprs[j] end return res end @@ -1740,7 +1746,7 @@ redef class ASendExpr do var recv = v.expr(self.n_expr) if recv == null then return null - var args = v.varargize(callsite.mpropdef, recv, self.raw_arguments) + var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments) if args == null then return null var res = v.callsite(callsite, args) @@ -1753,7 +1759,7 @@ redef class ASendReassignFormExpr do var recv = v.expr(self.n_expr) if recv == null then return - var args = v.varargize(callsite.mpropdef, recv, self.raw_arguments) + var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments) if args == null then return var value = v.expr(self.n_value) if value == null then return @@ -1777,29 +1783,35 @@ redef class ASuperExpr var callsite = self.callsite if callsite != null then - var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs) - if args == null then return null - # Add additional arguments for the super init call - if args.length == 1 then + var args + if self.n_args.n_exprs.is_empty then + # Add automatic arguments for the super init call + args = [recv] for i in [0..callsite.msignature.arity[ do args.add(v.frame.arguments[i+1]) end + else + args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs) + if args == null then return null end + # Super init call var res = v.callsite(callsite, args) return res end - # standard call-next-method + # Standard call-next-method var mpropdef = self.mpropdef mpropdef = mpropdef.lookup_next_definition(v.mainmodule, recv.mtype) - var args = v.varargize(mpropdef, recv, self.n_args.n_exprs) - if args == null then return null - - if args.length == 1 then + var args + if self.n_args.n_exprs.is_empty then args = v.frame.arguments + else + args = v.varargize(mpropdef, signaturemap, recv, self.n_args.n_exprs) + if args == null then return null end + var res = v.call(mpropdef, args) return res end @@ -1814,7 +1826,7 @@ redef class ANewExpr var callsite = self.callsite if callsite == null then return recv - var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs) + var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs) if args == null then return null var res2 = v.callsite(callsite, args) if res2 != null then @@ -1876,6 +1888,13 @@ redef class AIssetAttrExpr end end +redef class AVarargExpr + redef fun expr(v) + do + return v.expr(self.n_expr) + end +end + redef class ADebugTypeExpr redef fun stmt(v) do diff --git a/src/modelize/modelize_property.nit b/src/modelize/modelize_property.nit index 9cc9580..c0d3890 100644 --- a/src/modelize/modelize_property.nit +++ b/src/modelize/modelize_property.nit @@ -790,11 +790,17 @@ redef class AMethPropdef name = amethodid.collect_text name_node = amethodid - if name == "+" and self.n_signature.n_params.length == 0 then + var arity = self.n_signature.n_params.length + if name == "+" and arity == 0 then name = "unary +" - end - if name == "-" and self.n_signature.n_params.length == 0 then + else if name == "-" and arity == 0 then name = "unary -" + else + if amethodid.is_binary and arity != 1 then + modelbuilder.error(self.n_signature, "Syntax Error: binary operator `{name}` requires exactly one parameter; got {arity}.") + else if amethodid.min_arity > arity then + modelbuilder.error(self.n_signature, "Syntax Error: `{name}` requires at least {amethodid.min_arity} parameter(s); got {arity}.") + end end end @@ -868,6 +874,9 @@ redef class AMethPropdef end end + var accept_special_last_parameter = self.n_methid == null or self.n_methid.accept_special_last_parameter + var return_is_mandatory = self.n_methid != null and self.n_methid.return_is_mandatory + # Retrieve info from the signature AST var param_names = new Array[String] # Names of parameters from the AST var param_types = new Array[MType] # Types of parameters from the AST @@ -941,6 +950,14 @@ redef class AMethPropdef # In `new`-factories, the return type is by default the classtype. if ret_type == null and mpropdef.mproperty.is_new then ret_type = mclassdef.mclass.mclass_type + # Special checks for operator methods + if not accept_special_last_parameter and mparameters.not_empty and mparameters.last.is_vararg then + modelbuilder.error(self.n_signature.n_params.last, "Error: illegal variadic parameter `{mparameters.last}` for `{mpropdef.mproperty.name}`.") + end + if ret_type == null and return_is_mandatory then + modelbuilder.error(self.n_methid, "Error: mandatory return type for `{mpropdef.mproperty.name}`.") + end + msignature = new MSignature(mparameters, ret_type) mpropdef.msignature = msignature mpropdef.is_abstract = self.get_single_annotation("abstract", modelbuilder) != null @@ -1022,6 +1039,56 @@ redef class AMethPropdef end end +redef class AMethid + # Is a return required? + # + # * True for operators and brackets. + # * False for id and assignment. + fun return_is_mandatory: Bool do return true + + # Can the last parameter be special like a vararg? + # + # * False for operators: the last one is in fact the only one. + # * False for assignments: it is the right part of the assignment. + # * True for ids and brackets. + fun accept_special_last_parameter: Bool do return false + + # The minimum required number of parameters. + # + # * 1 for binary operators + # * 1 for brackets + # * 1 for assignments + # * 2 for bracket assignments + # * 0 for ids + fun min_arity: Int do return 1 + + # Is the `self` a binary operator? + fun is_binary: Bool do return true +end + +redef class AIdMethid + redef fun return_is_mandatory do return false + redef fun accept_special_last_parameter do return true + redef fun min_arity do return 0 + redef fun is_binary do return false +end + +redef class ABraMethid + redef fun accept_special_last_parameter do return true + redef fun is_binary do return false +end + +redef class ABraassignMethid + redef fun return_is_mandatory do return false + redef fun min_arity do return 2 + redef fun is_binary do return false +end + +redef class AAssignMethid + redef fun return_is_mandatory do return false + redef fun is_binary do return false +end + redef class AAttrPropdef redef type MPROPDEF: MAttributeDef diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index 7ef06e0..8fe169d 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -398,47 +398,58 @@ private class TypeVisitor # Visit the expressions of args and check their conformity with the corresponding type in signature # The point of this method is to handle varargs correctly # Note: The signature must be correctly adapted - fun check_signature(node: ANode, args: Array[AExpr], mproperty: MProperty, msignature: MSignature): Bool + fun check_signature(node: ANode, args: Array[AExpr], mproperty: MProperty, msignature: MSignature): nullable SignatureMap do var vararg_rank = msignature.vararg_rank if vararg_rank >= 0 then if args.length < msignature.arity then modelbuilder.error(node, "Error: expected at least {msignature.arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.") - return false + return null end else if args.length != msignature.arity then modelbuilder.error(node, "Error: expected {msignature.arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.") - return false + return null end #debug("CALL {unsafe_type}.{msignature}") + # Associate each parameter to a position in the arguments + var map = new SignatureMap + var vararg_decl = args.length - msignature.arity + var j = 0 for i in [0..msignature.arity[ do - var j = i - if i == vararg_rank then continue # skip the vararg - if i > vararg_rank then - j = i + vararg_decl + var param = msignature.mparameters[i] + var arg = args[j] + map.map[i] = j + j += 1 + + if i == vararg_rank then + j += vararg_decl + continue # skip the vararg end - var paramtype = msignature.mparameters[i].mtype - self.visit_expr_subtype(args[j], paramtype) + + var paramtype = param.mtype + self.visit_expr_subtype(arg, paramtype) end if vararg_rank >= 0 then var paramtype = msignature.mparameters[vararg_rank].mtype var first = args[vararg_rank] if vararg_decl == 0 and first isa AVarargExpr then var mclass = get_mclass(node, "Array") - if mclass == null then return false # Forward error + if mclass == null then return null # Forward error var array_mtype = mclass.get_mtype([paramtype]) self.visit_expr_subtype(first.n_expr, array_mtype) first.mtype = first.n_expr.mtype else - for j in [vararg_rank..vararg_rank+vararg_decl] do - self.visit_expr_subtype(args[j], paramtype) + map.vararg_decl = vararg_decl + 1 + for i in [vararg_rank..vararg_rank+vararg_decl] do + self.visit_expr_subtype(args[i], paramtype) end end end - return true + + return map end fun error(node: ANode, message: String) @@ -508,6 +519,20 @@ private class TypeVisitor end end +# Mapping between parameters and arguments in a call. +# +# Parameters and arguments are not stored in the class but referenced by their position (starting from 0) +# +# The point of this class is to help engine and other things to map arguments in the AST to parameters of the model. +class SignatureMap + # Associate a parameter to an argument + var map = new ArrayMap[Int, Int] + + # The length of the vararg sequence + # 0 if no vararg or if reverse vararg (cf `AVarargExpr`) + var vararg_decl: Int = 0 +end + # A specific method call site with its associated informations. class CallSite # The associated node for location @@ -540,9 +565,15 @@ class CallSite # Is a implicit cast required on erasure typing policy? var erasure_cast: Bool + # The mapping used on the call to associate arguments to parameters + # If null then no specific association is required. + var signaturemap: nullable SignatureMap = null + private fun check_signature(v: TypeVisitor, args: Array[AExpr]): Bool do - return v.check_signature(self.node, args, self.mproperty, self.msignature) + var map = v.check_signature(self.node, args, self.mproperty, self.msignature) + signaturemap = map + return map == null end end @@ -1737,7 +1768,7 @@ redef class ASuperExpr msignature = v.resolve_for(msignature, recvtype, true).as(MSignature) var args = self.n_args.to_a if args.length > 0 then - v.check_signature(self, args, mproperty, msignature) + signaturemap = v.check_signature(self, args, mproperty, msignature) end self.mtype = msignature.return_mtype self.is_typed = true @@ -1745,6 +1776,10 @@ redef class ASuperExpr mpropdef = v.mpropdef.as(MMethodDef) end + # The mapping used on the call to associate arguments to parameters. + # If null then no specific association is required. + var signaturemap: nullable SignatureMap + private fun process_superinit(v: TypeVisitor) do var anchor = v.anchor diff --git a/tests/error_operators.nit b/tests/error_operators.nit new file mode 100644 index 0000000..db94029 --- /dev/null +++ b/tests/error_operators.nit @@ -0,0 +1,91 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# no return +class A + fun + do abort + fun +(a: A) do abort + fun - do abort + fun -(a: A) do abort + fun *(a: A) do abort + fun /(a: A) do abort + fun %(a: A) do abort + fun <(a: A) do abort + fun >(a: A) do abort + fun <=(a: A) do abort + fun >=(a: A) do abort + fun <=>(a: A) do abort + fun <<(a: A) do abort + fun >>(a: A) do abort + fun foo=(a: A) do abort # should be fine + fun [](a: A) do abort + fun []=(a, b: A) do abort # should be fine +end + +# not enough parameters +class B + fun +: A do abort # should be fine + fun -: A do abort # should be fine + fun *: A do abort + fun /: A do abort + fun %: A do abort + fun <: A do abort + fun >: A do abort + fun <=: A do abort + fun >=: A do abort + fun <=>: A do abort + fun <<: A do abort + fun >>: A do abort + fun foo= do abort + fun []: A do abort + fun []=(a: A) do abort +end + +# too much parameters +class C + fun +(a,b,c:A): A do abort + fun -(a,b,c:A): A do abort + fun *(a,b,c:A): A do abort + fun /(a,b,c:A): A do abort + fun %(a,b,c:A): A do abort + fun <(a,b,c:A): A do abort + fun >(a,b,c:A): A do abort + fun <=(a,b,c:A): A do abort + fun >=(a,b,c:A): A do abort + fun <=>(a,b,c:A): A do abort + fun <<(a,b,c:A): A do abort + fun >>(a,b,c:A): A do abort + fun foo=(a,b,c:A) do abort # should be fine + fun [](a,b,c:A): A do abort # should be fine + fun []=(a,b,c:A) do abort # should be fine +end + +# bad vararg +class D + fun +(a:A...): A do abort + fun -(a:A...): A do abort + fun *(a:A...): A do abort + fun /(a:A...): A do abort + fun %(a:A...): A do abort + fun <(a:A...): A do abort + fun >(a:A...): A do abort + fun <=(a:A...): A do abort + fun >=(a:A...): A do abort + fun <=>(a:A...): A do abort + fun <<(a:A...): A do abort + fun >>(a:A...): A do abort + fun foo=(a,b,c:A, d:A...) do abort + fun [](a,b,c:A, d:A...): A do abort # should be fine + fun []=(a,b,c:A, d:A...) do abort +end diff --git a/tests/sav/error_operators.res b/tests/sav/error_operators.res new file mode 100644 index 0000000..1949e18 --- /dev/null +++ b/tests/sav/error_operators.res @@ -0,0 +1,54 @@ +error_operators.nit:17,6: Error: mandatory return type for `unary +`. +error_operators.nit:18,6: Error: mandatory return type for `+`. +error_operators.nit:19,6: Error: mandatory return type for `unary -`. +error_operators.nit:20,6: Error: mandatory return type for `-`. +error_operators.nit:21,6: Error: mandatory return type for `*`. +error_operators.nit:22,6: Error: mandatory return type for `/`. +error_operators.nit:23,6: Error: mandatory return type for `%`. +error_operators.nit:24,6: Error: mandatory return type for `<`. +error_operators.nit:25,6: Error: mandatory return type for `>`. +error_operators.nit:26,6--7: Error: mandatory return type for `<=`. +error_operators.nit:27,6--7: Error: mandatory return type for `>=`. +error_operators.nit:28,6--8: Error: mandatory return type for `<=>`. +error_operators.nit:29,6--7: Error: mandatory return type for `<<`. +error_operators.nit:30,6--7: Error: mandatory return type for `>>`. +error_operators.nit:32,6--7: Error: mandatory return type for `[]`. +error_operators.nit:40,9: Syntax Error: binary operator `*` requires exactly one parameter; got 0. +error_operators.nit:41,9: Syntax Error: binary operator `/` requires exactly one parameter; got 0. +error_operators.nit:42,9: Syntax Error: binary operator `%` requires exactly one parameter; got 0. +error_operators.nit:43,9: Syntax Error: binary operator `<` requires exactly one parameter; got 0. +error_operators.nit:44,9: Syntax Error: binary operator `>` requires exactly one parameter; got 0. +error_operators.nit:45,10: Syntax Error: binary operator `<=` requires exactly one parameter; got 0. +error_operators.nit:46,10: Syntax Error: binary operator `>=` requires exactly one parameter; got 0. +error_operators.nit:47,11: Syntax Error: binary operator `<=>` requires exactly one parameter; got 0. +error_operators.nit:48,10: Syntax Error: binary operator `<<` requires exactly one parameter; got 0. +error_operators.nit:49,10: Syntax Error: binary operator `>>` requires exactly one parameter; got 0. +error_operators.nit:50,14: Syntax Error: `foo=` requires at least 1 parameter(s); got 0. +error_operators.nit:51,10: Syntax Error: `[]` requires at least 1 parameter(s); got 0. +error_operators.nit:52,9--14: Syntax Error: `[]=` requires at least 2 parameter(s); got 1. +error_operators.nit:57,7--18: Syntax Error: binary operator `+` requires exactly one parameter; got 3. +error_operators.nit:58,7--18: Syntax Error: binary operator `-` requires exactly one parameter; got 3. +error_operators.nit:59,7--18: Syntax Error: binary operator `*` requires exactly one parameter; got 3. +error_operators.nit:60,7--18: Syntax Error: binary operator `/` requires exactly one parameter; got 3. +error_operators.nit:61,7--18: Syntax Error: binary operator `%` requires exactly one parameter; got 3. +error_operators.nit:62,7--18: Syntax Error: binary operator `<` requires exactly one parameter; got 3. +error_operators.nit:63,7--18: Syntax Error: binary operator `>` requires exactly one parameter; got 3. +error_operators.nit:64,8--19: Syntax Error: binary operator `<=` requires exactly one parameter; got 3. +error_operators.nit:65,8--19: Syntax Error: binary operator `>=` requires exactly one parameter; got 3. +error_operators.nit:66,9--20: Syntax Error: binary operator `<=>` requires exactly one parameter; got 3. +error_operators.nit:67,8--19: Syntax Error: binary operator `<<` requires exactly one parameter; got 3. +error_operators.nit:68,8--19: Syntax Error: binary operator `>>` requires exactly one parameter; got 3. +error_operators.nit:76,8--13: Error: illegal variadic parameter `a: A...` for `+`. +error_operators.nit:77,8--13: Error: illegal variadic parameter `a: A...` for `-`. +error_operators.nit:78,8--13: Error: illegal variadic parameter `a: A...` for `*`. +error_operators.nit:79,8--13: Error: illegal variadic parameter `a: A...` for `/`. +error_operators.nit:80,8--13: Error: illegal variadic parameter `a: A...` for `%`. +error_operators.nit:81,8--13: Error: illegal variadic parameter `a: A...` for `<`. +error_operators.nit:82,8--13: Error: illegal variadic parameter `a: A...` for `>`. +error_operators.nit:83,9--14: Error: illegal variadic parameter `a: A...` for `<=`. +error_operators.nit:84,9--14: Error: illegal variadic parameter `a: A...` for `>=`. +error_operators.nit:85,10--15: Error: illegal variadic parameter `a: A...` for `<=>`. +error_operators.nit:86,9--14: Error: illegal variadic parameter `a: A...` for `<<`. +error_operators.nit:87,9--14: Error: illegal variadic parameter `a: A...` for `>>`. +error_operators.nit:88,20--25: Error: illegal variadic parameter `d: A...` for `foo=`. +error_operators.nit:90,19--24: Error: illegal variadic parameter `d: A...` for `[]=`. diff --git a/tests/sav/test_ffi_c_operators.res b/tests/sav/test_ffi_c_operators.res index e80f5de..893e1ea 100644 --- a/tests/sav/test_ffi_c_operators.res +++ b/tests/sav/test_ffi_c_operators.res @@ -20,6 +20,8 @@ false false true true +32 +8 52 456 123 diff --git a/tests/sav/test_new_native_alt1.res b/tests/sav/test_new_native_alt1.res index 5789941..43e3636 100644 --- a/tests/sav/test_new_native_alt1.res +++ b/tests/sav/test_new_native_alt1.res @@ -1,4 +1,4 @@ -Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:911) +Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:960) NativeString N Nit diff --git a/tests/test_ffi_c_operators.nit b/tests/test_ffi_c_operators.nit index 271589e..5261b5e 100644 --- a/tests/test_ffi_c_operators.nit +++ b/tests/test_ffi_c_operators.nit @@ -102,14 +102,16 @@ class A return A_value( recv ) <= A_value( other ); `} - fun >>( other : A ) import value, value=, A `{ + fun >>( other : A ): A import value, value=, A `{ int new_val = A_value( recv ) >> A_value( other ); A_value__assign( recv, new_val ); + return recv; `} - fun <<( other : A ) import value, A `{ + fun <<( other : A ): A import value, A `{ int new_val = A_value( recv ) << A_value( other ); A_value__assign( recv, new_val ); + return recv; `} fun []( index : Int ) : A import A `{ @@ -154,13 +156,13 @@ print new A( 1 ) >= new A( 100 ) # false print new A( 100 ) >= new A( 100 ) # true print new A( 100 ) >= new A( 1 ) # true -#var x = new A( 1 ) -#x << new A( 5 ) -#print x # 16 +var x = new A( 1 ) +x = x << new A( 5 ) +print x # 32 -#var y = new A( 32 ) -#y >> new A( 2 ) -#print y # 8 +var y = new A( 32 ) +y = y >> new A( 2 ) +print y # 8 var a = new A( 456 ) print a[ 52 ] # 52