free software resistance
the cost of computing freedom is eternal vigilance
### fig-os-prototype-02
*originally posted:* nov 2024
this program is a prototype reference implementation for a language similar to fig.
version 2 adds support for loops and fixes various issues, including a bug in the first version that should have limited possible numeric values to a single digit.
```
#!/usr/bin/env pypy2
# coding: utf-8
# 2015-2024 by mn
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
proginf = "fig os prototype 0.2, nov 2024 mn"
# this is a repl implementation of a dialect based on fig.
# while it should become practical to use for something,
# the actual purpose is a reference implementation prototype
# for fig os, which would not be python-based.
import sys
import os ; os.system('')
from sys import stdin, stdout
from os import popen
def figindentcode(p, indent):
return chr(32) * figatleast(0, indent) + p
def bufproc(cbuf, cvar, vars, userfuncs, indent):
if len(cbuf) == 1:
if cbuf[0].lower() == "next":
cout = ""
#if figatleast(0, indent - 4): cout = [cout]
print "cout NEXT", indent
return cout
if len(cbuf[0]):
if cbuf[0][0] in ".1234567890-":
cout = figindentcode(cvar + " = " + cbuf[0], indent)
print "cout", cout
return cout
if cbuf[0][0] == chr(34):
cout = figindentcode(cvar + " = " + cbuf[0], indent)
print "cout", cout
return cout
if cbuf[0].lower() == "print":
cout = figindentcode("print(" + cvar + ")", indent)
print "cout", cout
return cout
if cbuf[0].lower() == "getvars":
cout = figindentcode(cvar + " = " + chr(34) + "['" + "', '".join(vars) + "']" + chr(34), indent)
if indent: cout = [cout]
print "cout", cout
return cout
if len(cbuf) == 2:
if cbuf[0].lower() == "forin":
if cbuf[1].lower() in vars:
cbuf[1] = cbuf[1].lower()
cout = figindentcode("for " + cvar + " in " + cbuf[1] + ":", indent)
print "cout", cout
return cout
if len(cbuf) == 2:
if cbuf[0].lower() == "get":
if cbuf[1].lower() in vars:
cbuf[1] = cbuf[1].lower()
cout = figindentcode(cvar + " = " + cbuf[1], indent)
print "cout", cout
return cout
if cbuf[0].lower() == "divby":
if cbuf[1].lower() in vars:
cbuf[1] = cbuf[1].lower()
cout = figindentcode(cvar + " = figdivby(" + cvar + ", " + cbuf[1] + ")", indent)
print "cout", cout
return cout
cout = chr(32) * figatleast(0, indent)
print cout
return cout
def figatleast(s, p):
if p < s:
return s
else:
return p
def figdivby(p, s):
p = float(p) / s
if p == float(int(p)):
p = int(p)
return p
def figarrshell(c):
global figsysteme
try:
figsysteme = 0
sh = figpo(c)
ps = sh.read().replace(chr(13) + chr(10),
chr(10)).replace(chr(13), chr(10)).split(chr(10))
figsysteme = sh.close()
except:
print "error running arrshell command: " + chr(34) + str(c) + chr(34)
figend(1)
return ps[:]
def figsgn(p):
p = float(p)
if p > 0:
return 1
if p < 0:
return -1
return 0
def figstr(p):
return str(p)
def figprint(p):
print p
def figchr(p):
if type(p) == str:
if len(p) > 0:
return p[0]
return chr(p)
def figprints(p):
stdout.write(str(p))
sys.stdout.flush()
def figleft(p, s):
return p[:s]
def figmid(p, s, x):
arr = 0
if type(p) == list or type(p) == tuple:
arr = 1
rt = p[s - 1:
x + s - 1]
if arr and len(rt) == 1:
rt = rt[0]
return rt
def figright(p, s):
return p[-s:]
def figlcase(p):
return p.lower()
def figucase(p):
return p.upper()
def figint(p):
return int(p)
def figarrset(x, p, s):
if type(s) == tuple:
if len(s) == 1: fas = s[0]
elif type(s) == list:
if len(s) == 1: fas = s[0]
else:
fas = s
x[p - 1] = s
def figcls(x):
if figosname == "nt":
cls = figsh("cls")
else:
stdout.write("\x1b[2J\x1b[1;1H")
sys.stdout.flush()
def figarropen(x, s):
p = open(s)
f = p.read().replace(chr(13) + chr(10), chr(10)).replace(chr(13),
chr(10)).split(chr(10))
p.close()
return f[:]
def figarrcurl(x, s):
from urllib import urlopen
x = str(urlopen(s).read())
x = x.replace(chr(13) + chr(10),
chr(10)).replace(chr(13), chr(10)).split(chr(10))
return x[:]
def figarrstdin(x):
ps = []
for p in stdin:
ps += [p[:-1]]
return ps[:]
def figarrget(x, p, s):
if 1:
return p[s - 1]
def figplus(p, s):
if type(p) in (float, int):
if type(s) in (float, int):
p = p + s
else:
p = p + s # float(s) if you want it easier
if p == float(int(p)):
p = int(p)
else:
if type(p) == str: p = p + s # str(s) if you want it easier
if type(p) == list:
if type(s) == tuple:
p = p + list(s)
elif type(s) == list:
p = p + s[:]
else:
p = p + [s]
if type(p) == tuple:
if type(s) == tuple:
p = tuple(list(p) + list(s))
elif type(s) == list:
p = tuple(list(p) + s[:])
else:
p = tuple(list(p) + [s])
return p
def figjoin(p, x, s):
t = ""
if len(x):
t = str(x[0])
for c in range(len(x)):
if c > 0: t += str(s) + str(x[c])
return t # s.join(x)
def figarr(p):
if type(p) in (float, int, str):
p = [p]
else:
p = list(p)
return p
def figsplit(p, x, s):
return x.split(s)
def figval(n):
n = float(n)
if float(int(n)) == float(n):
n = int(n)
return n
def figtimes(p, s):
if type(p) in (float, int):
p = p * s # float(s) if you want it easier
if p == float(int(p)):
p = int(p)
else:
if type(p) == list:
p = p[:] * s # figval(s)
else:
p = p * s # figval(s) if you want it easer
return p
def figdivby(p, s):
p = float(p) / s
if p == float(int(p)):
p = int(p)
return p
def figminus(p, s):
return p - s
def figtopwr(p, s):
p = p ** s
if p == float(int(p)):
p = int(p)
return p
def figmod(p, s):
return p % s
def figsqr(p):
from math import sqrt
p = sqrt(p)
if p == float(int(p)):
p = int(p)
return p
def figlineinput(p):
return raw_input()
def figlen(p):
return len(p)
def figasc(p):
return ord(p[0])
def figend(x):
quit()
def figsystem(x):
quit()
def figcolortext(x, f):
b = 0
if f == None: f = 0
if b == None: b = 0
n = "0"
if f > 7:
n = "1"
f = f - 8
if f == 1: f = 4 ## switch ansi colours for qb colours
elif f == 4: f = 1 ## 1 = blue not red, 4 = red not blue, etc.
if f == 3: f = 6
elif f == 6: f = 3
if b > 7: b = b - 8
if b == 1: b = 4
elif b == 4: b = 1
if b == 3: b = 6
elif b == 6: b = 3
stdout.write("\x1b[" + n + ";" + str(30+f) + "m")
return "\\x1b[" + n + ";" + str(30+f) + ";" + str(40+b) + "m"
def figcolourtext(x, f):
global figcgapal
global figcgapalcopy
f24 = f
b = 0
if f == None: f = 0
if b == None: b = 0
n = "0"
if f > 7:
n = "1"
f = f - 8
if f == 1: f = 4 ## switch ansi colours for qb colours
elif f == 4: f = 1 ## 1 = blue not red, 4 = red not blue, etc.
if f == 3: f = 6
elif f == 6: f = 3
if b > 7: b = b - 8
if b == 1: b = 4
elif b == 4: b = 1
if b == 3: b = 6
elif b == 6: b = 3
if figcgapal == figcgapalcopy:
stdout.write("\x1b[" + n + ";" + str(30+f) + "m")
return "\x1b[" + n + ";" + str(30+f) + ";" + str(40+b) + "m"
else:
stdout.write("\x1b[38;2;" + str(figcgapal[f24][0]) + ";" +
str(figcgapal[f24][1]) + ";" + str(figcgapal[f24][2]) + "m")
return "\x1b[" + n + ";" + str(30+f) + ";" + str(40+b) + "m"
figcgapal = [(0, 0, 0), (0, 0, 170), (0, 170, 0), (0, 170, 170),
(170, 0, 0), (170, 0, 170), (170, 85, 0), (170, 170, 170),
(85, 85, 85), (85, 85, 255), (85, 255, 85), (85, 255, 255),
(255, 85, 85), (255, 85, 255), (255, 255, 85), (255, 255, 255)]
figcgapalcopy = figcgapal[:] # support 24bit colour hack
def figget(p, s):
return s
def fighighlight(x, b):
f = None
if f == None: f = 0
if b == None: b = 0
n = "0"
if f > 7:
n = "1"
f = f - 8
if f == 1: f = 4 ## switch ansi colours for qb colours
elif f == 4: f = 1 ## 1 = blue not red, 4 = red not blue, etc.
if f == 3: f = 6
elif f == 6: f = 3
if b > 7: b = b - 8
if b == 1: b = 4
elif b == 4: b = 1
if b == 3: b = 6
elif b == 6: b = 3
stdout.write("\x1b[" + n + str(40+b) + "m")
return "\x1b[" + n + str(40+b) + "m"
def figinstr(x, p, e):
try:
return p.index(e) + 1
except:
return 0
def figchdir(p):
try:
figoch(p)
except:
print "no such file or directory: " + str(p)
figend(1)
def figshell(p):
global figsysteme
try:
figsysteme = figsh(p)
except:
print "error running shell command: " + chr(34) + str(p) + chr(34)
figend(1)
def figarrshell(c):
global figsysteme
try:
figsysteme = 0
sh = figpo(c)
ps = sh.read().replace(chr(13) + chr(10),
chr(10)).replace(chr(13), chr(10)).split(chr(10))
figsysteme = sh.close()
except:
print "error running arrshell command: " + chr(34) + str(c) + chr(34)
figend(1)
return ps[:]
def figprocline(cln):
tokenbuf = []
stbuf = ""
inq = 0
cmt = 0
for each in cln.lstrip():
if each == chr(34):
if inq:
inq = 0
tokenbuf += [stbuf + chr(34)]
stbuf = ""
else:
inq = 1
stbuf += chr(34)
elif each == "#":
if inq == 0:
cmt = 1
if stbuf == "":
return tokenbuf
elif each == "|":
if inq == 0:
if cmt == 0:
if stbuf != "":
tokenbuf += [stbuf]
tokenbuf += ["|"]
stbuf = ""
elif each == ";":
if inq == 0:
if cmt == 0:
if stbuf != "":
tokenbuf += [stbuf]
tokenbuf += [";"]
stbuf = ""
elif each == "=":
if inq == 0:
if cmt == 0:
if stbuf != "":
tokenbuf += [stbuf]
tokenbuf += ["="]
stbuf = ""
elif each == " ":
if inq == 0:
if stbuf.rstrip() != "":
tokenbuf += [stbuf]
stbuf = ""
else:
if stbuf.rstrip() != "":
stbuf += " "
else:
if cmt == 0:
stbuf += each
if stbuf.rstrip() != "":
tokenbuf += [stbuf]
return tokenbuf
res = ["lineinput", "next", "system", "exit", "forin", "iftrue", "next"]
vars = []
userfuncs = []
pline = []
cvar = "base"
base = 0
indent = 0
ecbuf = []
while 1:
now = figcolourtext(0, 7)
now = fighighlight(0, 0)
figprompt = "[" * figatleast(int(indent / 4), 0)
if not figprompt:
figprompt = "]"
figprints(figprompt + " ")
cln = figlineinput(0)
haltp = 0
rec = 0
tc = cln.strip().split(" ")
if len(tc):
pline = figprocline(cln)
print pline
if len(pline):
rec = 1
if not pline[0].lower() in res:
try:
exec(pline[0].lower() + " = 0")
cvar = pline[0].lower()
print "cvar:", cvar
if not pline[0].lower() in res + vars:
vars += [pline[0].lower()]
print "vars", vars
except:
now = figcolourtext(0, 3)
print " unable to set variable:", pline[0]
now = figcolourtext(0, 7)
print
haltp = 1
else:
pline = ["|"] + pline
linebuf = pline[1:] + ["|"]
cbuf = []
if linebuf != ["|"] and haltp == 0:
print linebuf
bufpoint = 0
while haltp == 0:
each = linebuf[bufpoint]
if each in ['|', ';', '=']:
linebuf = linebuf[len(cbuf) + 1:]
if cbuf:
print "full command:", cbuf
ecmd = bufproc(cbuf, cvar, vars, userfuncs, indent)
if cbuf[0].lower() in ["next"]:
indent = figatleast(0, indent - 4)
if cbuf[0].lower() in ["forin", "iftrue"]:
indent = figatleast(0, indent + 4)
if indent > 0:
ecbuf += [ecmd]
print "ecbuf:", ecbuf
if indent == 0:
figml = chr(10).join(ecbuf + [ecmd])
ecbuf = []
print "figml:" + chr(10) + figml
try:
exec(figml)
except ZeroDivisionError:
now = figcolourtext(0, 3)
print " division by zero"
now = figcolourtext(0, 7)
print ""
except SyntaxError:
now = figcolourtext(0, 3)
print " command not used correctly"
now = figcolourtext(0, 7)
print ""
cbuf = []
bufpoint = 0
else:
cbuf += [each]
bufpoint += 1
if bufpoint >= len(linebuf):
break
if cln.lower().strip() in ["system", "exit"]:
print
break
if rec == 0:
now = figcolourtext(0, 3)
print " command not recognised or used correctly"
now = figcolourtext(0, 7)
print
```
license: 0-clause bsd
```
# 2018, 2019, 2020, 2021, 2022, 2023, 2024
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
```
=> https://freesoftwareresistance.neocities.org