src: implement unary plus
[nit.git] / src / compiler / abstract_compiler.nit
index 0baf216..2359c7d 100644 (file)
@@ -95,12 +95,12 @@ redef class ToolContext
                        # Default is nitstack
                        opt_stacktrace.value = "nitstack"
                else
-                       print "Error: unknown value `{st}` for --stacktrace. Use `none`, `libunwind`, `nitstack` or `auto`."
+                       print "Option Error: unknown value `{st}` for --stacktrace. Use `none`, `libunwind`, `nitstack` or `auto`."
                        exit(1)
                end
 
                if opt_output.value != null and opt_dir.value != null then
-                       print "Error: cannot use both --dir and --output"
+                       print "Option Error: cannot use both --dir and --output"
                        exit(1)
                end
 
@@ -463,16 +463,18 @@ endif
 
                var makeflags = self.toolcontext.opt_make_flags.value
                if makeflags == null then makeflags = ""
-               self.toolcontext.info("make -B -C {compile_dir} -f {makename} -j 4 {makeflags}", 2)
+
+               var command = "make -B -C {compile_dir} -f {makename} -j 4 {makeflags}"
+               self.toolcontext.info(command, 2)
 
                var res
                if self.toolcontext.verbose_level >= 3 then
-                       res = sys.system("make -B -C {compile_dir} -f {makename} -j 4 {makeflags} 2>&1")
+                       res = sys.system("{command} 2>&1")
                else
-                       res = sys.system("make -B -C {compile_dir} -f {makename} -j 4 {makeflags} 2>&1 >/dev/null")
+                       res = sys.system("{command} 2>&1 >/dev/null")
                end
                if res != 0 then
-                       toolcontext.error(null, "make failed! Error code: {res}.")
+                       toolcontext.error(null, "Compilation Error: `make` failed with error code: {res}. The command was `{command}`.")
                end
        end
 end
@@ -689,7 +691,7 @@ extern void nitni_global_ref_decr( struct nitni_ref *ref );
                var finalize_meth = mainmodule.try_get_primitive_method("finalize", finalizable_type.mclass)
 
                if finalize_meth == null then
-                       modelbuilder.toolcontext.error(null, "The `Finalizable` class doesn't declare the `finalize` method.")
+                       modelbuilder.toolcontext.error(null, "Error: the `Finalizable` class does not declare the `finalize` method.")
                        return
                end
 
@@ -1628,6 +1630,12 @@ abstract class AbstractCompilerVisitor
        fun stmt(nexpr: nullable AExpr)
        do
                if nexpr == null then return
+               if nexpr.mtype == null and not nexpr.is_typed then
+                       # Untyped expression.
+                       # Might mean dead code
+                       # So just return
+                       return
+               end
 
                var narray = nexpr.comprehension
                if narray != null then
@@ -1647,6 +1655,13 @@ abstract class AbstractCompilerVisitor
        # `mtype` is the expected return type, pass null if no specific type is expected.
        fun expr(nexpr: AExpr, mtype: nullable MType): RuntimeVariable
        do
+               if nexpr.mtype == null then
+                       # Untyped expression.
+                       # Might mean dead code
+                       # so return a placebo result
+                       if mtype == null then mtype = compiler.mainmodule.object_type
+                       return new_var(mtype)
+               end
                var old = self.current_node
                self.current_node = nexpr
                var res = nexpr.expr(self).as(not null)
@@ -2038,6 +2053,9 @@ redef class AMethPropdef
                        else if pname == "unary -" then
                                v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
                                return true
+                       else if pname == "unary +" then
+                               v.ret(arguments[0])
+                               return true
                        else if pname == "*" then
                                v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
                                return true
@@ -2149,6 +2167,9 @@ redef class AMethPropdef
                        else if pname == "unary -" then
                                v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
                                return true
+                       else if pname == "unary +" then
+                               v.ret(arguments[0])
+                               return true
                        else if pname == "succ" then
                                v.ret(v.new_expr("{arguments[0]}+1", ret.as(not null)))
                                return true
@@ -2521,6 +2542,13 @@ redef class ASelfExpr
        redef fun expr(v) do return v.frame.arguments.first
 end
 
+redef class AImplicitSelfExpr
+       redef fun expr(v) do
+               if not is_sys then return super
+               return v.new_expr("glob_sys", mtype.as(not null))
+       end
+end
+
 redef class AEscapeExpr
        redef fun stmt(v) do v.add("goto BREAK_{v.escapemark_name(self.escapemark)};")
 end
@@ -3139,7 +3167,7 @@ var modelbuilder = new ModelBuilder(model, toolcontext)
 
 var arguments = toolcontext.option_context.rest
 if arguments.length > 1 and toolcontext.opt_output.value != null then
-       print "Error: --output needs a single source file. Do you prefer --dir?"
+       print "Option Error: --output needs a single source file. Do you prefer --dir?"
        exit 1
 end