interpreter: Added support for prefixed chars
[nit.git] / src / interpreter / naive_interpreter.nit
index 189f293..213680e 100644 (file)
@@ -876,21 +876,27 @@ redef class AMethPropdef
                        v.call(superpd, arguments)
                end
 
+               # First, try intern
                if mpropdef.is_intern or mpropdef.is_extern then
                        var res = intern_call(v, mpropdef, arguments)
                        if res != v.error_instance then return res
                end
-
+               # Then, try extern
+               if mpropdef.is_extern then
+                       var res = call_extern(v, mpropdef, arguments, f)
+                       if res != v.error_instance then return res
+               end
+               # Else try block
                if n_block != null then
                        v.stmt(self.n_block)
                        return null
                end
 
+               # Fail if nothing succeed
                if mpropdef.is_intern then
                        fatal(v, "NOT YET IMPLEMENTED intern {mpropdef}")
                else if mpropdef.is_extern then
-                       var res = call_extern(v, mpropdef, arguments, f)
-                       if res != v.error_instance then return res
+                       fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
                else
                        fatal(v, "NOT YET IMPLEMENTED <wat?> {mpropdef}")
                end
@@ -900,7 +906,6 @@ redef class AMethPropdef
        # Call this extern method
        protected fun call_extern(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance], f: Frame): nullable Instance
        do
-               fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
                return v.error_instance
        end
 
@@ -975,6 +980,10 @@ redef class AMethPropdef
                                return v.bool_instance(recvval >= args[1].to_i)
                        else if pname == "<=>" then
                                return v.int_instance(recvval <=> args[1].to_i)
+                       else if pname == "&" then
+                               return v.int_instance(recvval & args[1].to_i)
+                       else if pname == "|" then
+                               return v.int_instance(recvval | args[1].to_i)
                        else if pname == "to_f" then
                                return v.float_instance(recvval.to_f)
                        else if pname == "to_b" then
@@ -1023,6 +1032,10 @@ redef class AMethPropdef
                                return v.bool_instance(recvval >= args[1].to_b)
                        else if pname == "<=>" then
                                return v.int_instance(recvval <=> args[1].to_b)
+                       else if pname == "&" then
+                               return v.byte_instance(recvval & args[1].to_b)
+                       else if pname == "|" then
+                               return v.byte_instance(recvval | args[1].to_b)
                        else if pname == "to_f" then
                                return v.float_instance(recvval.to_f)
                        else if pname == "to_i" then
@@ -1155,6 +1168,12 @@ redef class AMethPropdef
                        else if pname == "fast_cstring" then
                                var ns = recvval.fast_cstring(args[1].to_i)
                                return v.native_string_instance(ns.to_s)
+                       else if pname == "fetch_4_chars" then
+                               return v.int_instance(args[0].val.as(NativeString).fetch_4_chars(args[1].to_i))
+                       else if pname == "fetch_4_hchars" then
+                               return v.int_instance(args[0].val.as(NativeString).fetch_4_hchars(args[1].to_i))
+                       else if pname == "utf8_length" then
+                               return v.int_instance(args[0].val.as(NativeString).utf8_length(args[1].to_i, args[2].to_i))
                        end
                else if pname == "calloc_string" then
                        return v.native_string_instance_len(args[1].to_i)
@@ -1478,7 +1497,12 @@ redef class AAttrPropdef
                        return evaluate_expr(v, recv, f)
                else if mpropdef == mwritepropdef then
                        assert args.length == 2
-                       v.write_attribute(attr, recv, args[1])
+                       var arg = args[1]
+                       if is_optional and arg.mtype isa MNullType then
+                               var f = v.new_frame(self, mpropdef, args)
+                               arg = evaluate_expr(v, recv, f)
+                       end
+                       v.write_attribute(attr, recv, arg)
                        return null
                else
                        abort
@@ -1534,14 +1558,14 @@ end
 
 redef class AClassdef
        # Execute an implicit `mpropdef` associated with the current node.
-       private fun call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
+       private fun call(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance]): nullable Instance
        do
                if mpropdef.mproperty.is_root_init then
-                       assert args.length == 1
+                       assert arguments.length == 1
                        if not mpropdef.is_intro then
                                # standard call-next-method
-                               var superpd = mpropdef.lookup_next_definition(v.mainmodule, args.first.mtype)
-                               v.call(superpd, args)
+                               var superpd = mpropdef.lookup_next_definition(v.mainmodule, arguments.first.mtype)
+                               v.call(superpd, arguments)
                        end
                        return null
                else
@@ -1910,6 +1934,8 @@ end
 redef class ACharExpr
        redef fun expr(v)
        do
+               if is_ascii then return v.byte_instance(self.value.as(not null).ascii)
+               if is_code_point then return v.int_instance(self.value.as(not null).code_point)
                return v.char_instance(self.value.as(not null))
        end
 end