IEN (Is Everything Number) Interpreter

Hi All,

The Joyfulprogrammer site is down.
I posted at retrogamecoding.org (see links from here) but you have to be registered for attachments access.

So I can't just link to these places with all this stuff, so here goes...

Moving on up from the BF Interpreter and the BQ a slight modification, moving up from these two impossible interpreters to program, I have developed IEN (from EIN) that solves the problem of how to do decision branching. It also makes it easier to load memory locations with values to serve as variables and to use special memory locations for Binary Operations for numeric and 0 or 1 for Boolean results. Still extremely primitive and small but I can write the program for the Hi Lo Game with it.

Hi Lo Game written for IEN Interpreter:

P Z100 M4 Z1 A0 F3 A4 B3 * M3 Z2 A0 B3 F3 Z1 A0 B3 + M3
[ C69 C110 C116 C101 C114 C32 C97 C32 C103 C117 C101 C115 C115 C32 C102 C111 C114 C32 C109 C121 C32 C110 C117 C109 C98 C101 C114 C32 C98 C101 C116 C119 C101 C101 C110 C32 C49 C32 C97 C110 C100 C32 C49 C48 C48 C32 ?4
A4 B10 =
I
X
N
A4 B3 >
I

C72 C105 C103 C104 P
E
<
I
C76 C111 C119 P
E
C82 C105 C103 C104 C116 C33 P
X
N
N
P
]


*** A Sample Hi Lo Game Decoded ***

The first line creates the secret number:P Z100 M4 Z1 A0 F3 A4 B3 * M3 Z2 A0 B3 F3 Z1 A0 B3 + M3

P is just Print to start a new line
Z100 loads 100 into memory 0, Z for zero.
M4 stores what is in memory(0) to another memory location, in this case memory(4)
Z1 1 to memory(0)
A0 An moves what is at memory(n) to memory(1), so here memory(0) gets copied into memory(1)
F3 Fn calls a Function by number in memory(1) since we moved 1 there it calls RND since RND doesn't need to work on a value we don't have to check what is in memory(2) loaded with command Bn which moves memory(n) to memory(2). The 3 in F3 means to store the result of the function named in memory(1) that worked on value in memory(2) to memory(3) in this case.
A4 moves contents of memory 4 to memory(1)
B3 moves contents of memory 3 to memory(2)
* multiplies memory(1) by memory(2) and stores result in memory(0), all the Binary Operators work just like that!
M3 now takes what is in memory(0) and copies it to memory(3)
Z2 loads memory(0) with 2
A0 copies memory(0) to memory(1)
B3 copies memory(3) to memory(2)
F3 calls the function number in memory(1) which is 2, this is the INT function applied to memory(2) and result stored in memory(3).
(Yeah the function calls are pretty complicated but do work step by step.)
Z1 copies 1 to memory(0)
A0 copies memory(0) to memory(1)
B3 copies memory(3) to memory(2)
+ adds memory(1) to memory(2) and stores result in memory(0)
M3 copies memory(0) to memory(3)

What we did was take a RND number multiply it by 100, round it down with INT (it is now a number between 0 and 99) then we add 1 to it (it is now a random integer from 1 to 100).

Ah Ha! now our secret number for the Hi Lo Game is set in memory(3) where it can be used as reference to compare with guesses.

In the next two lines:

[ starts a loop structure, call the symbol for DO.
All the Cn are just print the CHR(n); This is a prompt for ?4 (Input into memory(4)) at the end. Just putting the guess into memory(4).

A4 B10 = loads memory(1) and memory(2) the secret number and B10? but memory(10) is empty! so zero goes to memory(2)
What we are checking is if the guess was 0, if so that is our signal that the user wants to quit the game immediately.

I checks memory(0) and if = 0 then it will look for an E (else) or N (end if) and continue execution from that letter.

So if guess was 0 then X (exit) loop, look for ] and continue execution there.

A4 B3 > loads memory(4) to memory(1) and memory(3) to memory(2) and compares memory(1) > memory(2) putting result in memory(0).

I (if) after that, looks at memory(0), if memory(0) = 1 it continues on, if not it looks for E | N to continue from there.
So if the guess was greater than the secret number then it would print High with all the Cn's
Otherwise it will goto E
< compares if memory(1) < memory(2) is the guess < secret number (memory(1) and memory(2) already loaded with values to compare)

This is a test of a nested IF blocks and how they work in a loop structure.
If
the guess was < secret number Low would be printed E (else) well the guess must be = if not greater or less than secret number.
So after E (else) print Right! with the Cn's and then X (exit) the ] (loop)

Game over. When the "program" is printed in the output window, it is just a couple lines of letters and numbers. All the tabs, spaces and line feeds are stripped before the Interpreter works on executing the string. So all programs are one-liners to the IEN Interpreter. ;-))


'IEN Interpreter.bas for SmallBASIC 0.12.9 (B+=MGA) 2017-07-28 new name

memsize = 20000
DIM memory(memsize)
numChars = "-.1234567890"
cmdChars = "WC?ABZMIENP[X]F%^/*~+=<>()!&|"
allChars = numChars + cmdChars

while 1
color 0, 11 : cls
anyfile = files("IEN*.txt")
sort anyfile
? "EIN (Everything Is Numbered) Files:":?
if len(anyfile) > 0 then
for i = 0 to ubound(anyfile)
? i, anyfile(i)
next
? : input "Enter file NUMBER (any else quits) > ", flnm
if isnumber(flnm) then
if flnm >= 0 and flmn <=ubound(anyfile) then
getfile = anyfile(flnm)
tload getfile, source, 1
else
stop
end if
else
stop
end if
else
? "No files found" : source = ""
end if
color 7, 1 : cls
if source <> "" then
for i = 1 to len(source)
? mid(source, i, 1);
if i mod 60 = 0 then ?
next
?
end if
?:input "n(New) e(Edit) r(Run) k(Kill) q(Quits) other(Files)"; menu
select case ucase(left(menu,1))
case "N" : input "Enter a title, for *IEN + title + DATE.TXT* format ";tl
dt = right(date,4) + "-" + mid(date,4,2) + "-" + left(date,2)
fname = "IEN " + tl + " " + dt + ".txt"
OPEN fname FOR OUTPUT AS #1
CLOSE #1
RUN "notepad " + fname
case "E" : run "notepad "+ getfile
case "K" : kill getfile
case "Q" : end
case "R" : color 7, 0 : cls : runSource
end select
wend

SUB
runSource
source = UCASE(source)
'let's clean the code up, check bracket balance
bktCnt = 0 : ifCnt = 0 : code = ""
FOR i = 1 TO len(source)
char = MID(source, i, 1)
'check to see if this is a valid instruction character
IF INSTR(allChars, char) THEN
code = code + char
'count brackets
IF char = "[" THEN bktCnt = bktCnt + 1
IF char = "]" THEN bktCnt = bktCnt - 1
if char = "I" Then ifCnt = ifCnt + 1
if char = "N" then ifCnt = ifCnt - 1
END IF
NEXT
IF bktCnt THEN 'mismatched brackets
? "Uneven brackets" : PAUSE : EXIT SUB
ELSEIF ifCnt THEN
? "Uneven I N counts" : PAUSE : EXIT SUB
ELSE
? code 'check
END IF
ERASE memory
DIM memory(memsize)
cmd = "" : ds = "" : err = ""
FOR i = 1 TO LEN(code) 'loop through the code
c = MID(code, i, 1) 'get the instruction we're on
IF INSTR("-.1234567890", c) THEN ds = ds + c
IF INSTR(cmdChars, c) OR i = len(code) THEN 'hit next command or end
IF cmd <> "" THEN 'execute unfinished command
d = VAL(ds)
'exec last cmd
SELECT CASE cmd
CASE "A" : memory(1) = memory(d)
CASE "B" : memory(2) = memory(d)
CASE "Z" : memory(0) = d
CASE "M" : memory(d) = memory(0)
CASE "F"
SELECT CASE memory(1)
CASE 0 : if memory(2) <> 0 then memory(d) = 0 else memory(d) = 1
CASE 1 : memory(d) = RND
CASE 2 : memory(d) = INT(memory(2))
END SELECT
CASE "W" : ? memory(d);
case "C" : ? chr(d);
CASE "?" : input test
if isstring(test) then test = val(test)
memory(d) = test
END SELECT
cmd = "" : ds = ""
END IF 'if cmd <> ""

'handle current cmd
IF INSTR("WC?ABZMF", c) THEN 'get d first
cmd = c
ELSEIF c = "I" : IF memory(0) = 0 then Findi
IF err <> "" THEN ? err : PAUSE : EXIT SUB
ELSEIF c = "E" THEN
Findi
IF err <> "" THEN ? err : PAUSE : EXIT SUB
ELSEIF c = "P" THEN
?
ELSEIF c = "X" THEN
bktCnt = 1 'count the bracket we're on
i = i + 1 'move the code pointer to the next char
WHILE bktCnt <> 0
'count nested loops till we find the matching one
IF MID(code, i, 1) = "]" THEN bktCnt = bktCnt - 1
IF MID(code, i, 1) = "[" THEN bktCnt = bktCnt + 1
i = i + 1 'search forward
WEND
i = i - 1
ELSEIF c = "]" THEN ' end a loop if loop index is 0
bktCnt = -1'count the bracket we're on
i = i - 1'move the code pointer back a char
WHILE bktCnt <> 0
'count nested loops till we fine the matching one
IF MID(code, i, 1) = "]" THEN bktCnt = bktCnt - 1
IF MID(code, i, 1) = "[" THEN bktCnt = bktCnt + 1
i = i - 1 'search backwards
WEND
i = i + 1 '<<< ??? doesn't seem to matter i+1, i-1 or nothing
ELSEIF c = "%" THEN : memory(0) = memory(1) % memory(2)
ELSEIF c = "^" THEN : memory(0) = memory(1) ^ memory(2)
ELSEIF c = "/" THEN : memory(0) = memory(1) / memory(2)
ELSEIF c = "*" THEN : memory(0) = memory(1) * memory(2)
ELSEIF c = "~" THEN : memory(0) = memory(1) - memory(2)
ELSEIF c = "+" THEN : memory(0) = memory(1) + memory(2)
ELSEIF c = "=" THEN : memory(0) = memory(1) = memory(2)
ELSEIF c = "<" THEN : memory(0) = memory(1) < memory(2)
ELSEIF c = ">" THEN : memory(0) = memory(1) > memory(2)
ELSEIF c = "(" THEN : memory(0) = memory(1) <= memory(2)
ELSEIF c = ")" THEN : memory(0) = memory(1) >= memory(2)
ELSEIF c = "!" THEN : memory(0) = memory(1) <> memory(2)
ELSEIF c = "&" THEN : memory(0) = memory(1) and memory(2)
ELSEIF c = "|" THEN : memory(0) = memory(1) or memory(2)
END IF
END IF ' ran into next command
'? mid(code, i, 1); :input temp
NEXT
?:? "Run is done, hit any..." : pause
END
SUB

SUB
Findi
'code, i, err are global
LOCAL cnt, c1, j
cnt = 1
FOR j = i + 1 TO LEN(code)
c1 = MID(code, j, 1)
IF c1 = "N" THEN
cnt = cnt - 1
IF cnt = 0 THEN i = j : EXIT SUB
ELSEIF c1 = "I" THEN
cnt = cnt + 1
ELSEIF c1 = "E" and cnt = 1 THEN
i = j : EXIT SUB
END IF
NEXT
err = "Could not find N"
END
SUB

IEN (Is Everything Number) Interpreter

This is a sort of evolving process starting from the
BrainF*** Interpreter > BQ Interpreter to EIN
solves problem of how to do IF ELSE END IF stuff
to IEN which adds unary functions to the mix.

All commands are a single command letter/symbol,
some are followed by numbers some are not.
All spaces, CR, LF, Tabs... are stripped before the
Interpreter goes to work executing commands.

Number digits/symbols:
-.1234567890 are reserved for number values.
Note: - sign is just used for making a number value
negative; the ~ sign is actually used for the binary
operation of subtraction.

Command Characters:
cmdChars = "WC?ABZMFIENP[X]%^/*~+=<>()!&|"

These commands are followed by a number (n):
WC?ABZMF

Wn - Writes a number from memory(n), the cursor stays where it is.
Cn - writes Chr(n) and cursor stays put also, eg C32 prints a space.
?n - Gets Input and stores it into memory(n).
An - stores memory(n) into memory(1)
Bn - stores memory(n) into memory(2)

(All the Binary Operators %^/*~+=<>()!&| perform their assigned task with
memory(1) and memory(2) and store the results in memory(0).
So you can see Memory(0-2) are specially reserved.)

Zn - stores n into memory(0)
Mn - takes memory(0) and stores it to memory(n)
(So a Zn Mn combination loads a variable with a value.)

Fn - n will be the memory location for the result to go
Place the Function number to use in memory(1)
NOT = 0
RND = 1
INT = 2
Steps
1. Zn set your function number
2. A0 set memory(1) from memory(0)
3. Bn set the memory location for value the function is to convert
4. Fn set in memory(n) the value

These commands are NOT followed by numbers: IENP[X] and all the operators.

IEN are for If Else and eNdif, I checks memory(0) to see if it should
seek E|N when memory(0) = 0 or stay with the next code if
memory(0) <> 0. When E is hit from I block we look for N on same level.
N is just there as marker.

P just starts next printing on next line.

[X] are the 3 command letters for loop structure:
[ is like DO and ] is like LOOP. X is for eXit, your only way out of the loop.

%^/*~+=<>()!&| Operators:
An Bn load memory(1) and memory(2) then an operator evaluates the
relation and stores the value in memory(0). W0, I, Mn all read memory(0).

14 Binary Operator Symbols:

6 Numeric Return Operators:
% is MOD or Modulus eg 10 % 3 = 1
^ is power 10 ^ 3 = 1000
/ is divide 10 / 3 = 1.3333...
* is multiply 10 * 3 = 30
~ is subtraction NOT - used to make a number negative 10 ~ 3 = 7

*** Repeat use ~ for Subtraction NOT - sign. ***

+ is addition 10 + 3 = 13

8 Booleans return operators false = 0 , true 1 is set for when NOT = 0
= is Equal test returns 1 in memory(0) if true else 0
< is Less Than test, 10 < 3 returns 0 in memory(0)
> is Greater Than test, 10 > 3 returns 1 in memory(0)
( is Less Than or Equal test <= 10 ( 3 returns 0 in memory(0)
) is GreaterThan or Equal >= test, 10 ) 3 returns 1 in memory(0)
Notice curves of: < ( and > ) best one symbol to replace two?
! is for not, here it means NOT Equal <> or !=
& is for AND if memory(1) <> 0 AND memory(2) <> 0, then 1 in memory(0)
| is used for OR so if either memory(1) <> 0 OR memory(2) <> 0,
then memory(0) =(set to) 1 else memory(0) =(set to) 0

Some IEN programs written to test and debug the Interpreter:

IEN test Binary operators.txt

Z2M1Z5M2
W1C32C63c32W2C32c61P
W1C32C37c32W2C32c61C32
%W0P
W1C32C94c32W2C32c61c32
^W0P
W1C32C47c32W2C32c61C32
/W0P
W1C32C42c32W2C32c61c32
*W0P
W1C32C126c32W2C32c61c32
~W0P
W1C32C43c32W2C32c61c32
+W0P
W1C32C61c32W2C32c62c32
=W0P
W1C32C60c32W2C32c62c32
<W0P
W1C32C62c32W2C32c62c32
>W0P
W1C32C40c32W2C32c62c32
(W0P
W1C32C41c32W2C32c62c32
)W0P
W1C32C33c32W2C32c62c32
!W0P
W1C32C38c32W2C32c62c32
&W0P
W1C32C124c32W2C32c62c32
|W0P
PC66C43P

IEN test count.txt

z2m3z0m4z10m5
[A4B5(IW4PA4B3+M4EXN]PC66C43P

IEN test Count Generalized.txt

C69 C110 C116 C101 C114 C32 C83 C116 C97 C114 C116 C32 C62 C32 ?4
C69 C110 C116 C101 C114 C32 C69  C110  C100  C32 C62 C32 ?5
C69 C110 C116 C101 C114 C32 C83 C116 C101 C112 C32 C62 C32 ?3
C83 C116 C97 C114 C116 C32 C62 C32 W4P
C69  C110  C100  C32 C62 C32 W5P
C83 C116 C101 C112 C32 C62 C32 W3P
[A4B5(IW4PA4B3+M4EXN]P C66 C43 P

ASC Table.txt

In the next line space = 32 and ! = 33...
i=32-41:  ! " # $ % & ' ( ) 

i=42-51:* + , - . / 0 1 2 3

i=52-61:4 5 6 7 8 9 : ; < =

i=62-71:> ? @ A B C D E F G

i=72-81:H I J K L M N O P Q

i=82-91:R S T U V W X Y Z [

i=92-101:\ ] ^ _ ` a b c d e

i=102-111:f g h i j k l m n o

i=112-121:p q r s t u v w x y

i=122-131:z { | } ~

.bas to Convert Strings for IEN programs:

' Convert String to C ASC numbers.bas SmallBASIC 0.12.9 (B+=MGA) 2017-07-28
'
'    Type in the text lines you need for an IEN program.
'    This program will create a file: "Converted Strings.txt"
'    You may copy / paste the code lines needed to print
'    the text lines in the IEN program.

l = chr(13) + chr(10)
open "Converted strings.txt" for output as #1
While 1
  ? "Enter a string to convert to *C Asc* numbers."
  lineinput s
  b = ""
  if s = "" then end
  for i = 1 to len(s)
    c = mid(s, i, 1)
    a = asc(c)
    b = b + "C" + str(a) + " "
  next
  ? "For string: " + s
  ? b
  print #1, s + l
  print #1, b + l
  print #1, " " + l
wend
close #1

Sample Converted Strings made for the Hi Lo Game:

Enter a guess for my number between 1 and 100

C69 C110 C116 C101 C114 C32 C97 C32 C103 C117 C101 C115 C115 C32 C102 C111 C114 C32 C109 C121 C32 C110 C117 C109 C98 C101 C114 C32 C98 C101 C116 C119 C101 C101 C110 C32 C49 C32 C97 C110 C100 C32 C49 C48 C48 C32

High

C72 C105 C103 C104

Low

C76 C111 C119

Right!

C82 C105 C103 C104 C116 C33