android & benitlux: use NitObject in clients
[nit.git] / contrib / brainfuck / brainfuck.nit
index b614776..d207496 100644 (file)
 module brainfuck
 
 # Interpreter for Brainfuck source code.
-class BFInterpret
+class BFInterpreter
        # Data cells
-       var dr = new Array[Char]
+       var dr = new Array[Int]
        # Data pointer
        var dp = 0
        # Instruction pointer
        var ip = 0
 
        # The program being interpreted
-       var program: String
+       var program: Bytes
 
-       # Contains the set of valid instructions, used in next
-       var valid_instr: Set[Char]
+       # Create an interpreter for `program`.
+       init do
+               dr.add 0
+       end
 
-       # Starts interpretation of file `filename`
-       init(filename: String) do
-               var ifs = new IFStream.open(filename.simplify_path)
-               valid_instr = new HashSet[Char]
-               valid_instr.add_all "><[].,+-".chars
-               dr.add 0.ascii
-               program = ifs.read_all
-               start
+       # Create an interpreter for the file located at `path`.
+       init from_file(path: String) do
+               var ifs = new FileReader.open(path)
+               init(ifs.read_all_bytes)
        end
 
        # Starts the interpretation of the loaded program
@@ -45,50 +43,43 @@ class BFInterpret
                loop
                        if ip >= program.length then break
                        eval
-                       next
-               end
-       end
-
-       # Go to the next executable instruction
-       fun next do
-               ip += 1
-               while ip < program.length and not valid_instr.has(program[ip]) do
                        ip += 1
                end
        end
 
+
        # Evaluates the current instruction
        fun eval do
                var instr = program[ip]
-               if instr == '.' then printn dr[dp]
-               if instr == '[' then
-                       if dr[dp] == 0.ascii then
+               if instr == u'.' then printn dr[dp].code_point
+               if instr == u'[' then
+                       if dr[dp] == 0 then
                                ip = find_matching_rbra
                                return
                        end
                end
-               if instr == ']' then
-                       if dr[dp] != 0.ascii then
+               if instr == u']' then
+                       if dr[dp] != 0 then
                                ip = find_matching_lbra
                                return
                        end
                end
-               if instr == '>' then
+               if instr == u'>' then
                        dp += 1
-                       if dp >= dr.length then dr.add(0.ascii)
+                       if dp >= dr.length then dr.add(0)
                end
-               if instr == '<' then
+               if instr == u'<' then
                        dp -= 1
                        if dp < 0 then abort
                end
-               if instr == '+' then
-                       dr[dp] = (dr[dp].ascii + 1).ascii
+               if instr == u'+' then
+                       dr[dp] = dr[dp] + 1
                end
-               if instr == '-' then
-                       dr[dp] = (dr[dp].ascii - 1).ascii
+               if instr == u'-' then
+                       dr[dp] = dr[dp] - 1
                end
-               if instr == ',' then
-                       dr[dp] = getc
+               if instr == u',' then
+                       dr[dp] = getc.code_point
                end
        end
 
@@ -98,14 +89,14 @@ class BFInterpret
                var lbracnt = 0
                loop
                        if pos > program.length then abort
-                       if program[pos] == ']' then
+                       if program[pos] == u']' then
                                if lbracnt > 0 then
                                        lbracnt -= 1
                                else
                                        break
                                end
                        end
-                       if program[pos] == '[' then lbracnt += 1
+                       if program[pos] == u'[' then lbracnt += 1
                        pos += 1
                end
                return pos
@@ -117,18 +108,18 @@ class BFInterpret
                var rbracnt = 0
                loop
                        if pos < 0 then abort
-                       if program[pos] == '[' then
+                       if program[pos] == u'[' then
                                if rbracnt > 0 then
                                        rbracnt -= 1
                                else
                                        break
                                end
                        end
-                       if program[pos] == ']' then rbracnt += 1
+                       if program[pos] == u']' then rbracnt += 1
                        pos -= 1
                end
                return pos
        end
 end
 
-var i = new BFInterpret(args[0])
+new BFInterpreter.from_file(args[0]).start