ive never cared much for syntax highlighting

code-1839406_960_720

 

syntax highlighting is meant to make it easier to read and manage code. its not intended as training wheels, but a tool for professionals and students alike.

i find it draws attention away– if only a small amount of it– from what im trying to do. there are also at least two problems with syntax highlighting, regarding the colours chosen: first, that the parts of syntax that need the brightest or most vibrant colours (that draw the most attention) follow the same logic for everyone. just for a random example, in the picture above the items in red– a colour used for “stop” and “warning” because it gets the most attention– are the tag names, and the equals sign. a more useful scheme to me would be if = was one colour, and == was a different colour (to make assignment vs comparison easier to spot.)

its different for every person. i dont need the tag names in red– theyre already marked with a chevron to the left. thats what im looking for to find tag names. yes, red certainly makes it easier to find the tags (or equals signs) but the whole time im coding, those tags now try to pull me away from the rest of the code. its not worth the tradeoff.

the other problem with colours chosen is that at any given time, what im really looking for in code is a specific group of things, and it changes based on context. so while im looking for whatever it is that im looking for, (it might not even be syntax) ive got all this colourful noise in the text im searching through. now picture a needle in a haystack: do you want to look for that silver needle in a bale of ordinary blonde hay, or would it be easier if the hay were eight or nine different colours?

i find highlighting very useful for search results– especially multiple results displayed at once:

leafpad

 

but i only use the search feature if a quick look over the page doesnt suffice, and syntax highlighting only gets the way.

im inclined to think that syntax highlighting is something a lot of people just “put up with” because its there, and its “too much bother” to turn off. (most people hate configuring anything in general, unless they need to and they cant.) and im sure its useful at least for most of the people that make it a feature in the editors theyre writing. it would be funny if that werent the case– if everyone thought that everyone else preferred highlighting, so developers that didnt want or need it assumed they had to add it for the users, while users assumed there was benefit (because why else have the feature?)

its even possible that syntax highlighting is a fad, but im sure a lot of people either love it, or think they do. i gravitate towards editors that dont have it, and i will turn it off if i have to.

 

 

figbuzz: a programming language for writing fizzbuzz (requires python 2)

figbuzz is a program written in python– it translates a language called “figbuzz” into python. if this sounds a lot like fig, theres a good reason. figbuzz is a stripped-down fig compiler.

at 955 lines, figbuzz contains all the block functions of fig, plus the commands needed to write fizzbuzz, plus a command called “ismultipleof”. this demo (included in the download) will look familiar to those who know my fizzbuzz program written in fig:

#### license: creative commons cc0 1.0 (public domain)
#### http://creativecommons.org/publicdomain/zero/1.0/
for fb 1 100 1
    while
        ifmultipleof fb 5
            ifmultipleof fb 3
                now "fizzbuzz" print
                break
                fig
            fig
        ifmultipleof fb 5
            now "buzz" print
            break
            fig
        ifmultipleof fb 3
            now "fizz" print
            break
            fig
        now fb print
        break
        wend
    next

 

save the above program as fb.figb (or whatever-you-like.figb) and figbuzz will translate it into whatever-you-like.figb.py

figbuzz is not only an over-the-top fizzbuzz demo, its also a slightly more manageable version of fig to experiment with. everything is there, minus more than 50 of the usual commands.

figbuzz does not do graphics, figbuzz does not do colour. figbuzz does not require libraries, figbuzz only needs python 2.

(fig only needs python 2 in gnu/linux and mac os/x, but in windows it requires colorama.)

here is the source for figbuzz:

#!/usr/bin/env python
# coding: utf-8 
#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 
proginf = "figbuzz 0.1, apr 2017 mn"
# a version of fig just for writing fizzbuzz
import sys
import os
from sys import stdin, stdout
from os import popen

buf = []

cmdhelp = [("timer", "input (shared-line) change main variable to number of seconds past midnight")

,("print", "output (shared-line) output main variable to the screen (aka stdout)")
,("prints", "output (shared-line) put main var to screen; like print but (s)tays on line.")
,("while", "loop --\\own\\line mark the start of a loop (will keep going without break)")
,("break", "loop --\\own\\line put in the middle of a loop to exit (stop looping)")
,("for var strt stop step", "loop --\\own\\line start a for loop, changing var from strt to stop, by step")
,("forin var array", "loop --\\own\\line loop through each item in array; for each, set var to item")
,("iftrue ckvar", "conditional --\\own\\line run lines between iftrue and fig if ckvar is \"non-zero\"")
,("ifequal var1 var2", "conditional --\\own\\line run lines between ifequal and fig if var1 equals var2")
,("ifmore var1 var2", "conditional --\\own\\line run lines between ifmore and fig if var1 is > var2")
,("ifless var1 var2", "conditional --\\own\\line run lines between ifless and fig if var1 is < var2")
,("ifmultipleof var1 var2", "conditional --\\own\\line run lines between ifless and fig if var1 is divisible evenly by var2")
,("try", "conditional --\\own\\line put code that might not work between try and except")
,("except", "conditional --\\own\\line if code between try/except fails, run the code after except")
,("resume", "conditional --\\own\\line mark the end of try / except / resume command block")
,("else", "conditional --\\own\\line after if- line, before fig. run lines if condition isnt true")
,("function name p1 p2 ...¦", "function --\\own\\line define function named name with optional params p1,p2, etc")
,("fig/next/nextin/wend", "fig (interchangeable) function --\\own\\line finalise a block (started by if/while/function/for/forin")
,("pass", "function --\\own\\line blocks (for/next, etc) require something inside lines; pass works / does nothing")
,("str", "function (shared-line) convert main variable from number to string")
,("not", "function (shared-line) change main variable to zero if non-zero; or -1 if zero")
,("#", "comment (can\\share) place at beginning (or end) of line, prior to a comment")
,("():;|=,. ( ) : ; | = , .", "optional (shared-line) use in a shared line (and some others) for aesthetics/notation")
,("system", "function (shared-line) put on (usually at the end of) a line to stop the program")
,("end", "function (shared-line) interchangeable with system which ends the program")
,("return var", "function (shared-line) (optional) exit current function, returning value var")
,("swap var1 var2", "function (shared-line) change contents of var1 to contents of var2 and vice-versa")
,("plus numstrarr", "math (shared-line) change main variable to itself plus num or string or arr")
,("minus numeric", "math (shared-line) change main variable to itself minus numeric")
,("divby numeric", "math (shared-line) change main variable to itself divided by numeric")
,("times numeric", "math (shared-line) change main variable to itself times numeric")
,("sgn", "math (shared-line) change main variable to 0 if 0, to -1 if < 0, or 1 if > 0.")
,("int", "math (shared-line) change main variable from decimal (aka \"float\") to integer")
,("mod denominator", "math (shared-line) change main variable to: main var modulus denominator")]

def chelp(f):
    ck = 0 ; print "" 
    for p in cmdhelp:
        rcmd = p[0]
        if f in rcmd.split()[0]:
            ck = 1
            rd = p[1].split()
            rcat = rd[0] ; rd.remove(rd[0])
            rt = rd[0] ; rd.remove(rd[0])

            cde = rcmd.split(" ")
            print "" 
            stdout.write("    " + colour(14,0)+ cde[0])
            cda = cde.remove(cde[0])
            for c in cde:
                stdout.write(" " + colour(0, 7)+ " " + c + " " + colour(7,0)+" ") ; stdout.flush()
            print "" 
            print "" 
            print colour(3,0) + "        category:", rcat, rt.replace("\\", " ") 
            print "" 
            print "        " + colour(7,0) + " ".join(rd) 
            print "" 
        colour(7,0);
    return ck

def outfilewrite(outb, p):
    outb += [p]
    #global vrck 
    #vrck += p.strip()
    #if inle: print colour(5, 0) + p.rstrip() ; p=raw_input() ; quit()

def colour(f, b):
    stdout.write("")
    return ""

def bcolour(b):
    stdout.write("")
    return ""

def sgn(p):
    p = float(p)
    if p > 0: return 1
    if p < 0: return -1
    return 0

def left(p, s):
    return p[:s]

def right(p, s):
    return p[-s:]

def leftfour(p):
    try: 
        if left(p, 4) == chr(32) * 4: p = right(p, len(p) - 4)
    except:
        pass
    return p

def atleast(s, p):
    if p < s: return s
    else: return p

def figfsp(p):
    pp = "" ; flg = 0 
    fsp = figfsplit(p)    
    for fp in enumerate(fsp):
        if flg == 0 and fp[1] in cmds.keys():
            pp += colour(8,0) + "_" + colour(7,0) + " " ; flg = cmds[fp[1]]
            if flg < 0: flg = flg * -1
            else: flg = flg + 1
        pp += fp[1] + " "
        if flg > 0:
            flg -= 1 
            if flg == 0 and fp[0] + 1 < len(fsp):
                pp += colour(8,0) + "_" + colour(7,0) + " "
    return pp.rstrip().replace(colour(8,0) + "_" + colour(7,0) + " " + colour(8,0) + 
    "_" + colour(7,0), colour(8,0) + "__" + colour(7,0)).replace(colour(8,0) + "_" + 
    colour(7,0),colour(8,0) + "__" + colour(7,0))

def figfsplit(p):
    # return p.split() # that was fine when strings weren't tokens
    # we have to make this 3 tokens: variable "hello, world!" #comment not string

    px = [] 
    pxc = -1 # could use len(px) -1 instead?

    inquotes = 0
    remarked = 0
    inspc = "" ; vnspc = ""

    #print "->", p

    for l in p:
        if inquotes == 0 and remarked == 0 and l == "#":
            remarked = 1
            pxc += 1 ; px += [""]
        if remarked == 1:
            px[pxc] += l

        if remarked == 0:
            if l == "\"":
                if inquotes == 0:
                    inquotes = 1 ; pxc += 1 ; px += [""]
                else: inquotes = 0 #; px[pxc] += l
        if inquotes == 1: px[pxc] += l

        if remarked == 0 and inquotes == 0:
            if vnspc not in "1234567890-" + chr(32) and l[0] == ".": l = " "
            vnspc = l
            if l[0] in "():;|=,": l = " "
            if inspc != " " and l == " ": pxc += 1 ; px += [""]
            if l != " ":
                if pxc == -1: pxc += 1 ; px += [""]
                px[pxc] += l.lower() 
            inspc = l
    #print "->", px[:]
    while ('') in px: px.remove('')
    while (':') in px: px.remove(':')
    for p in range(len(px)):
        if px[p][0] != "#":
            if right(px[p], 1) == ":":
                lenpx = len(px[p]) - 1
                if lenpx > 0:
                    px[p] = left(px[p], lenpx)
    return px[:]

def nob(p, s):
    r = ""
    if s == len(p) - 1:
        if len(p):
            if p[s].rstrip() != ".": r = p[s].rstrip()
        if len(r):
            if r[-1:] == ".": r = left(r, len(r) - 1)
    pfig = ""
    try: pfig = left(p[s], 3)
    except: pfig = ""
    if pfig.lower() == "fig" and p[s].lower() != "fig": return "figg"
    try: 
        if r != "": return r
        else: return p[s]
    except: return ""

def snobl(p):
    if "\"" in p: return p
    else: return p.lower()

def snob(p, s):
    r = ""
    if s == len(p) - 1:
        if len(p):
            if p[s].rstrip() != ".": r = p[s].rstrip()
        if len(r):
            if r[-1:] == ".": r = left(r, len(r) - 1)
    pqt = ""
    try: pqt = left(p[s], 3)
    except: pqt = ""
    if pqt.lower() == "fig" and p[s].lower() != "fig": return "figg"
    try: 
        if r != "": return snobl(r)
        else: return snobl(p[s])
    except: return ""

def lnob(p, s):
    r = ""
    if s == len(p) - 1:
        if len(p):
            if p[s].rstrip() != ".": r = p[s].rstrip()
        if len(r):
            if r[-1:] == ".": r = left(r, len(r) - 1)
    pfig = ""
    try: pfig = left(p[s], 3)
    except: pfig = ""
    if pfig.lower() == "fig" and p[s].lower() != "fig": return "figg"
    try: 
        if r != "": return r.lower()
        else: return p[s].lower()
    except: return ""

def getmore(p, s):
    try:
        for t in range(1, s + 1):
            if len(p) == 1: p = []
            p = right(p, len(p) - 1)
        while "" in p: p.remove("")
        for prx in range(len(p)):
            if p[prx][0] == "#":
                p.remove(p[prx])
        return p
    except: return []

def getlmore(p, s):
    try:
        for t in range(1, s + 1):
            if len(p) == 1: p = []
            p = right(p, len(p) - 1)
        while "" in p: p.remove("")
        return p
    except: return []

def lc():
    global linecount
    global flen
    es = " \x1b[0;37;40m"
    return "\x1b[0;37;44m" + right(chr(32) * flen + str(linecount), flen) + es

def wr(p):
    global buf
    buf += [p + "\n"]

colour(11, None) ; print proginf; colour(7, None) ; print

addtoout = [0]
addto = [0]

addtoout[0] = """import sys, os
from sys import stdin, stdout
from os import chdir as figoch
from os import popen as figpo
from os import system as figsh
from os import name as figosname
figsysteme = 0
figfilehandles = {}
figfilecounters = {}
"""

addtoout += [0] ; addto += [0]

addtoout[1] = """from sys import stdout
def fignonz(p, n=None):
    if n==None:
        if p == 0: return 1
    else:
        if p == 0: return n
    return p

def fignot(p):
    if p: return 0
    return -1

figbac = None
figprsbac = None
sub = None
def fignone(p, figbac):
    if p == None: return figbac
    return p
    return -1

\n"""
addtoout += [0] ; addto += [0]

addtoout[2] = ""
addtoout += [0] ; addto += [0]

addtoout[3] = ""

addtoout += [0] ; addto += [0]

# -2: print(variable, etc)
# -1: print(variable), 0: variable = int(variable), 1: variable=left(variable, etc)

cmds = {"str":0,
"prints":-1,"system":-1, "end":-1, 
"print":-1, 
"plus":1, "times":1, "divby":1, "minus":1,  
"int":0, "swap":-3, "return":-2, "mod":1, "not":0, "sgn":0}

funcs = {"function" : -1, "iftrue" : -2, "ifmultipleof" : -3, "ifequal" : -3, "ifless" : -3, 
"ifmore" : -3, "try":0, "except":0, "resume":0, "else":0}

ufunc = {}

#addfuncs = addtoout[0] + addtoout[1] + addtoout[3] + """
addfuncs = """

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 figprints(p): stdout.write(str(p)) ; sys.stdout.flush()

def figint(p): return int(p)

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 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 figmod(p, s): 
    return p % s

def figfunction(p, s): return p
def figend(x): quit()

def figsystem(x): quit()
\n"""

demo = """
for fb 1 100 1
    while
        ifmultipleof fb 5
            ifmultipleof fb 3
                now "fizzbuzz" print
                break
                fig
            fig
        ifmultipleof fb 5
            now "buzz" print
            break
            fig
        ifmultipleof fb 3
            now "fizz" print
            break
            fig
        now fb print
        break
        wend
    next
"""

p = ""
try: p = right(sys.argv, 1)[0]
except: pass
if not ".figb" in p.lower():
    if p.lower() == "help":
        stdout.write("\n    type (any) part of the command you want help on." +
        "\n\n    fig will show all matches.\n\n\n    ")
        helpf = chelp(raw_input())
        if not helpf: print(colour(14,0)+"\n    no commands match your search.") ; print("")
        colour(7,0)
    #try: inputfile = stdin.read().replace(chr(13), "").split("\n")
    #except: 
    #print "need an input file to do anything..."; print ; quit()
        quit()
    else:
        print "using built-in demo source, translating to demo.figb.py..." ; print
        p = "demo.figb"
        inputfile = demo.replace(chr(13), "").split("\n")
else:
    try:
        inputfile = open(p).read().replace(chr(13) + chr(10), 
        chr(10)).replace(chr(13), chr(10)).split(chr(10))
    except: print "couldn't open \"" + p + "\", exiting." ; print ; quit()
try: outfile = open(p + ".py", "w")
except: print "couldn't write to \"" + p + ".py" "\", exiting." ; print ; quit()
outname = p + ".py"

flen = len(str(len(inputfile)))

linecount = 0
indent = 0
inlinep = 0
inle = 0
errorin = 0
errorsrc = ""
error = ""
mode = 0
figraphics = -1 # -1 = uninitialised, 0 = textmode, 1 = initialised
vrs = []
vr = ""
outb = []
ingfx = 0
linesoutc = 0

for p in inputfile:
    linecount += 1 ; vrop = 0 ; vrcl = 0

    if linecount == 1: 
        outfile.write("#!/usr/bin/env python" + "\n# encoding: utf-8\n")
        if "," in proginf: 
            outfile.write("# figbuzz translator version: " + proginf.split(",")[0] + "\n")
    if inlinep:
        if p.lower().strip() == "fig":
            inlinep = 0
            print lc() + p
            indent = atleast(0, indent - 4)
        else:
            print lc() + colour(2, None) + p + colour(7, None)
            #% write copied lines of inline python
            outfilewrite(outb, chr(32) * atleast(0, indent - 4) + 
            leftfour(p) + "\n")

    elif mode == "output the following:":
        if p.lower().strip() == "display":
            mode = 0
            print lc() + p
        else:
            wr(chr(32) * atleast(0, indent) + "print \"" + p.replace(chr(34), 
            "\" + chr(34) + \"").replace(chr(92), "\" + chr(92) + \"") + "\"")
            print lc() + p.replace(chr(34), "\" + chr(34) + \"").replace(chr(92), 
            "\" + chr(92) + \"") 

    elif mode == 0:
        x = figfsplit(p.lstrip())
        lp = p.lower()
        if not len(p):
            print lc() + ""
            #% write copied blank lines from inline python
            outfilewrite(outb, "\n")

        if len(p.lstrip()):

            e = 0

            if p.lstrip()[0] == "#":
                if linecount == 1:
                    es = 0
                    try: 
                         if p.lstrip()[1] == "!": es = 1
                    except: es = 0
                    if not es:
                        wr(p)
                        print lc(), figfsp(p)
                    else: print lc() + "[this first comment isn't copied over]"
                    es = 0 
                else:
                    #% write comments
                    #print colour(14, 0) + p + colour(7,0) ; znul = raw_input()  #$ 
                    outfilewrite(outb, chr(32) * atleast(0, indent) + p + "\n")
                    print lc(), figfsp(p)

            elif lnob(x, 0) == "figg":
                 e = 2

            elif lp.rstrip() == "python":
                if 1 == 0:    
                    indent += 4
                    inlinep = 1
                    print lc() + p

            else:
                if not lnob(x, 0) == "figg":
                    if lnob(x, 0) != "fig" and not lnob(x, 
                    0) in cmds.keys() and not lnob(x, 
                    0) in funcs.keys() + ["forin", "for", "function", "nextin",
                    "next", "while", "wend"] + ["break", "pass"]: 
                        if not lnob(x, 0) in vrs: vrs += [lnob(x, 0)[:]] # main vars, also func params, etc
                        #% write variable
                        #var: print colour(14, 0) + "variable:" + lnob(x, 0) + colour(7,0) ; znul = raw_input()  #$
                        outfilewrite(outb, "\n")
                        outfilewrite(outb, chr(32) * atleast(0, indent) + 
                        "figlist = 0\n") 

                        outfilewrite(outb, chr(32) * atleast(0, indent) + 
                        "try: figlist = int(type(" + lnob(x, 0) + ") == list)\n")

                        outfilewrite(outb, chr(32) * atleast(0, indent) + 
                        "except NameError: pass\n")
                        outfilewrite(outb, chr(32) * atleast(0, indent) + 
                        "if not figlist: " + lnob(x, 0) + " = 0 \n")

                    if lnob(x, 0) == "fig":
                        #print lc () + p
                        #% write? its whitespace
                        #$
                        indent = atleast(0, indent - 4) 
                    if lnob(x, 0) == "wend":
                        #print lc () + p
                        #% write? its whitespace
                        #$
                        indent = atleast(0, indent - 4) 
                    if lnob(x, 0) == "next":
                        #print lc () + p
                        #% write? its whitespace
                        #$
                        indent = atleast(0, indent - 4) 
                    if lnob(x, 0) == "nextin":
                        #print lc () + p
                        #% write? its whitespace
                        #$
                        indent = atleast(0, indent - 4) 
                    if lnob(x, 0) == "try":
                        #print lc () + p
                        #% write try line
                        #$
                        outfilewrite(outb, chr(32) * atleast(0, indent) + "try:\n")
                        indent = atleast(0, indent + 4) 
                    if lnob(x, 0) == "else":
                        #print lc () + p
                        #% write else line
                        #$
                        outfilewrite(outb, chr(32) * atleast(0, indent - 4) + 
                        "else:\n")
                    if lnob(x, 0) == "except":
                        #print lc () + p
                        indent = atleast(0, indent - 4) 
                        #% write except line
                        #$
                        outfilewrite(outb, chr(32) * atleast(0, indent) + 
                        "except:\n")
                        indent = atleast(0, indent + 4) 
                    if lnob(x, 0) == "resume":
                        #print lc () + p
                        #% write? its whitespace
                        #$
                        indent = atleast(0, indent - 4) 
                    if lnob(x, 0) == "while":
                        #print lc () + p
                        #% write simple loop
                        #$
                        outfilewrite(outb, chr(32) * atleast(0, indent) + 
                        "while 1:\n")
                        indent += 4 
                    if lnob(x, 0) == "function" and len(getmore(x, 1)) > 0:
                        #print lc () + p
                        mkf = []
                        funcname = getlmore(x, 1)[0]
                        prm = 1
                        while 1:
                            try:
                                aprm = getlmore(x, 1)[prm]
                                if len(aprm): 
                                    if aprm[0] != "#":
                                        mkf += [aprm]
                                        if aprm not in vrs: vrs += [aprm[:]]
                                prm += 1
                            except: break
                        ufunc[funcname] = mkf[:] #; print ufunc # #
                        #print ufunc
                        #print len(ufunc[funcname])
                        #% write func def
                        #$ print colour(14,0)+ "def " +  funcname + "(" + ", ".join(mkf) + "):" + colour(7,0)
                        outfilewrite(outb, chr(32) * atleast(0, indent) + "def " +
                        funcname + "(" + ", ".join(mkf) + "):\n")
                        indent += 4

                    if lnob(x, 0) == "for" and len(getmore(x, 1)) == 4:
                        #print lc () + p
                        gmro = getlmore(x, 1)[0]
                        gmrt = getlmore(x, 1)[1]
                        gmrh = getlmore(x, 1)[2]
                        gmrf = getlmore(x, 1)[3]
                        if gmro not in vrs: vrs += [gmro[:]]
                        if "." not in gmrf and (gmrf.strip()) not in ("0", 
                        "0.0", "-0") and "." not in gmrt and "." not in gmrh: 
                            #% write standard for loop
                            #$
                            outfilewrite(outb, chr(32) * atleast(0, indent) 
                            + "for "
                            + gmro + " in range(int(float(" + gmrt + 
                            ")), int(float(" + gmrh + ")) + figsgn(" + gmrf + 
                            "), fignonz(int(float(" + gmrf + ")))):\n")
                        else:
                            #% write for loop that allows floating step
                            #$
                            outfilewrite(outb, chr(32) * atleast(0, indent) + gmro 
                            + " = float(" + gmrt + ") - float(" + gmrf + ")\n" + 
                            chr(32) * atleast(0, indent) + "while 1:\n" + chr(32) *
                            atleast(0, indent + 4) + gmro + " += float(" + gmrf +
                            ")\n" + chr(32) * atleast(0, indent + 4) + "if " + 
                            gmrf +
                            " > 0 and " + gmro + " > float(" + gmrh + "): break\n" 
                            + chr(32) * atleast(0, indent + 4) + "elif " + gmrf + 
                            " <= 0 and " + gmro + 
                            " < float(" + gmrh + "): break\n")
                        indent += 4

                    if lnob(x, 0) == "forin" and len(getmore(x, 1)) == 2:
                        #print lc () + p
                        gmro = getlmore(x, 1)[0]
                        gmrt = getlmore(x, 1)[1]
                        if gmro not in vrs: vrs += [gmro[:]]
                        #% write forin command with params
                        #$
                        outfilewrite(outb, chr(32) * atleast(0, indent) + "for " +
                        gmro + " in " + gmrt + ":\n")
                        indent += 4

                    if lnob(x, 0) == "break":
                        #print lc () + p
                        #% write break command
                        #$ print
                        outfilewrite(outb, chr(32) * 
                        atleast(0, indent) + "break\n") 

                    if lnob(x, 0) == "pass":
                        #print lc () + p
                        #% write pass command
                        #$ print
                        outfilewrite(outb, chr(32) *
                        atleast(0, indent) + "pass\n") 

                    if lnob(x, 0) == "iftrue":
                        #print lc () + p
                        #% write iftrue
                        #$ print colour(14,0) + "if " +    snob(x, 1) + " > " + snob(x, 2) + ":\n"+ " ; " +colour(7,0)
                        outfilewrite(outb, chr(32) * atleast(0, indent) + "if " + 
                        snob(x, 1) + ":\n") ; indent += 4

                    if lnob(x, 0) == "ifequal" and len(getmore(x, 1)) == 2:
                        #print lc () + p
                        #% write ifequal
                        #$ print colour(14,0) + "if " +    snob(x, 1) + " > " + snob(x, 2) + ":\n"+ " ; " +colour(7,0)
                        outfilewrite(outb, chr(32) * atleast(0, indent) + "if " + 
                        snob(x, 1) + " == " + snob(x, 2) + ":\n") ; indent += 4

                    if lnob(x, 0) == "ifless" and len(getmore(x, 1)) == 2:
                        #print lc () + p
                        #% write ifless
                        #$ print colour(14,0) + "if " +    snob(x, 1) + " > " + snob(x, 2) + ":\n"+ " ; " +colour(7,0)
                        outfilewrite(outb, chr(32) * atleast(0, indent) + "if " +
                        snob(x, 1) + " < " + snob(x, 2) + ":\n") ; indent += 4

                    if lnob(x, 0) == "ifmultipleof" and len(getmore(x, 1)) == 2:
                        #print lc () + p
                        #% write ifless
                        #$ print (colour(14,0) + "if " +    float(snob(x, 1)) + " / " + 
                        #snob(x, 2) + " == int(" +  snob(x, 1) + " / " + snob(x, 2) + "):\n"+ 
                        #" ; " +colour(7,0))
                        outfilewrite(outb, chr(32) * atleast(0, indent) + "if float(" +
                        snob(x, 1) + ") / " + snob(x, 2) + " == int(" + snob(x, 1) + " / " + 
                        snob(x, 2) + "):\n") ; indent += 4

                    if lnob(x, 0) == "ifmore" and len(getmore(x, 1)) == 2:
                        #print lc () + p
                        #% write ifmore
                        #$ print colour(14,0) + "if " +    snob(x, 1) + " > " + snob(x, 2) + ":\n"+ " ; " +colour(7,0)
                        outfilewrite(outb, chr(32) * atleast(0, indent) + "if " + 
                        snob(x, 1) + " > " + snob(x, 2) + ":\n") ; indent += 4

                    if lnob(x, 0) in cmds.keys(): # + ufunc.keys():
                        e = 4 ; shln = lnob(x, 0) 

                    if lnob(x, 0) != "fig" and lnob(x, 
                    0) not in funcs.keys() + ["forin", "for", "function", 
                    "nextin", "next", "while", "wend"] + ["break", "pass"]:

                        #print lc () + p
                        vr = lnob(x, 0)
                        #print vr, type(vr)
                        #print getlmore(x, 1)
                        prsc = 0
                        cstrctr = 0
                        csbuf = []
                        vrcs = ""
                        for prs in getlmore(x, 1):                            
                            #$ print prs 
                            if "fig" in prs:
                                if prs[:3] == "fig": e = 2 ; break ; break
                            if prs in funcs.keys():
                                e = 3 ; shln = prs
                            prsc += 1
                            if cstrctr > 0:
                                vrcs += prs
                                cstrctr -= 1
                                if cstrctr == 0:

                                    if lnob(x, prsc - 1) == "return":
                                        #% write return command
                                        #$ print colour(14,0) +vrcs + " ; " +colour(7,0)
                                        outfilewrite(outb, chr(32) * atleast(0, 
                                        indent) + vrcs)

                                    elif lnob(x, prsc - 2) == "swap":
                                        vrcs = lnob(x, prsc - 1) + ", " + lnob(x,
                                        prsc - 0) + " = " + lnob(x, 
                                        prsc - 0) + ", " + lnob(x, prsc - 1)
                                        #% write swap of 2 vars in python syntax
                                        #$ print colour(14,0) +vrcs + " ; " +colour(7,0)
                                        outfilewrite(outb, chr(32) * atleast(0,
                                        indent) + vrcs + " ; ")
                                    else:

                                        if figprsbac in ufunc.keys():
                                            #% write parametered func call 
                                            #$ print colour(14,0)+  vrcs + ") ; " + lnob(x, 0) + " = fignone(" + lnob(x, 0) + ", figbac) ; " +colour(7,0)
                                            outfilewrite(outb, chr(32) * atleast(0,
                                            indent) + vrcs + ") ; " + lnob(x, 0) +
                                            " = fignone(" + lnob(x, 0) +
                                            ", figbac) ; ") ; vrcl += 1
                                        else:
                                            #% write builtin func call assignment
                                            #$ print colour(14,0)+  vr + " = " +  vrcs + ") ; "  +colour(7,0)
                                            outfilewrite(outb, chr(32) *
                                            atleast(0, indent) + vrcs + ") ; ") ; vrcl += 1
                                else:
                                    vrcs += ", " #; print "*"
                                    #if 
                                continue

                            if prs.lower() in funcs.keys() + ["forin", "for",
                            "function", "nextin", "next", "while", 
                            "wend"] + ["break", "pass"]:
                                e = 3
                            figprsbac = None

                            if cstrctr == 0:
                                if not prs.lower() in vrs:
                                    if prs.lower()[0] in "abcdefghijklmnopqrstuvwxyz":
                                        if not prs.lower() in ufunc.keys():
                                            if not prs.lower() in funcs.keys():
                                                if not prs.lower() in cmds.keys():
                                                    e = 5 ; shln = prs

                            if prs.lower() in vrs and cstrctr == 0: 
                                #and len(getmore(x, 1)) == 1:
                                #% write lefthand variable assignment
                                #$ print colour(14,0)+  vr + " = " + prs.lower()  +colour(7,0)
                                outfilewrite(outb, chr(32) * atleast(0, indent) +
                                vr + " = " + prs.lower() + "\n")

                            if prs[0] == "\"":
                                #% write string assignment (any place in shared line)
                                outfilewrite(outb, chr(32) * atleast(0, indent) +
                                vr + " = " + prs + " ; ")

                            if prs[0] in ".1234567890-":
                                #% write numerics
                                outfilewrite(outb, chr(32) * atleast(0, indent) + 
                                vr + " = " + prs + " ; ")

                            if prs[0] == "#": 
                                #% write trailing comments #$ print colour(14, 0) + prs  + colour(7,0)
                                outfilewrite(outb, prs + "\n") ; break


                            if prs.lower() in ufunc.keys():
                                #% write pre-func-call var backup for sub-style behavior #$ print colour(14, 0) + "figbac = " + lnob(x,0) + " ; " + colour(7,0)
                                outfilewrite(outb, chr(32) * atleast(0, indent) +
                                "figbac = " + lnob(x,0) + " ; " ) # ##
                                figprsbac = prs.lower()	

                                cstrctr = len(ufunc[prs])
                                #print cstrctr
                                if cstrctr == 0:
                                    #% write zero-param func/?sub call
                                    #$ print colour(14, 0) + vr + " = " + prs.lower() + "() ; " + lnob(x, 0) + " = fignone(" + lnob(x, 0) + ", figbac) ; " + colour(7,0)
                                    outfilewrite(outb, chr(32) * 
                                    atleast(0, indent) + 
                                    vr + " = " + prs.lower() + "() ; " + lnob(x, 0) +
                                            " = fignone(" + lnob(x, 0) + ", figbac) ; ") # #
                                else:
                                    #print "y"
                                    vrop += 1
                                    vrcs = vr + " = " + prs.lower() + "(" 
                                    #$ print colour(4, 0) + vr + " = " + prs.lower() + "(" + colour(7,0) #$
                                    #multiparameter  


                            if prs.lower() in cmds.keys():
                                if prs.lower() in ["display", "pset", "line"]: 
                                    ingfx = 1
                                ##print prs	
                                cstrctr = cmds[prs]
                                ##print cstrctr
                                if cstrctr == -1:
                                    #% write zero-param subs
                                    #print colour(14, 0) + "fig" +  prs.lower() + "(" + vr 
                                    #+ ") ; " + colour(7,0) ; #znul = raw_input()  #$
                                    outfilewrite(outb, chr(32) * 
                                    atleast(0, indent) + "fig" + 
                                    prs.lower() + "(" + vr + ") ; " ) ; vrcl += 1

                                if cstrctr == 0:
                                    #% write zero-param functions 
                                    #print colour(14, 0) + vr + " = fig" + prs.lower() 
                                    #+ "(" + vr + ") ; "+ colour(7,0) ; #znul = raw_input()  #$
                                    outfilewrite(outb, chr(32) * atleast(0,
                                    indent) + vr +
                                    " = fig" + prs.lower() + "(" + vr + ") ; " ) ; vrcl += 1

                                if cstrctr < -1:
                                    if prs == "return":

                                        cstrctr = abs(cstrctr) - 1
                                        vrcs = "return " #parameter
                                    else:
                                        cstrctr = abs(cstrctr) - 1
                                        if prs == "swap": vrcs = "swap "
                                        else:
                                            vrop += 1
                                            vrcs = "fig" + prs.lower() + "(" + vr 
                                            vrcs += ", " #multiparameter  
                                else:
                                    vrop += 1
                                    vrcs = vr + " = fig" + prs.lower() + "(" + vr 
                                    vrcs += ", " #multiparameter  

                        if vrop == vrcl and e == 0: 
                            print lc(), figfsp(p)

                        #% finish each line with lf
                        outfilewrite(outb, "\n")
                    else:
                        print lc() + p
                else:
                    e = 2

            if e == 1: 
                e = 0 
                if not len(error):
                    error = "error: problem in command structure or details."
                    errorin = linecount
                    errorsrc = p
                print lc() + colour(14, 0) + str(p) + colour(7, 0)
                break

            if e == 2:
                e = 0
                if not len(error):
                    error = "error: cannot create variable or function beginning"
                    error += " with \"fig\""
                    errorin = linecount
                    errorsrc = p
                print lc() + colour(14, 0) + p + colour(7, 0)
                break

            if e == 3:
                e = 0
                if not len(error):
                    error = "error: single-line command \"" + shln + "\" not on own line"
                    errorin = linecount
                    errorsrc = p
                print lc() + colour(14, 0) + p + colour(7, 0)
                break

            if e == 4:
                e = 0
                if not len(error):
                    error = "error: shared-line function \""
                    error += shln + "\" cannot be used to start a line"
                    errorin = linecount
                    errorsrc = p
                print lc() + colour(14, 0) + p + colour(7, 0)
                break

            if e == 5:
                e = 0
                if not len(error):
                    error = "error: variable or function not created, but referenced... \""
                    error += shln + "\" needs to be set before first use"
                    errorin = linecount
                    errorsrc = p
                print lc() + colour(14, 0) + p + colour(7, 0)
                break

    if vrcl != vrop: 
                e = 0 
                if not len(error):
                    error = "error: a command has the wrong number of parameters."
                    errorin = linecount
                    errorsrc = p
                print lc() + colour(14, 0) + str(p) + colour(7, 0)
                break

if ingfx == 0: addtoout[3] = ""
outfile.write(addtoout[0] + addtoout[1] + addtoout[3] + addfuncs)
for outsb in outb: outfile.write(outsb)
outfile.close()

print
if errorin:
    print error ; colour(14, None) ; print "error in line " + str(errorin) + ":"
    colour(7, None)
    print errorsrc
    #from os import system as stf ; p = stf("touch e")
else:
    try: os.system("chmod +x \"" + outname + "\"")
    except: pass
    colour (11, None) ; print "translation complete. ", ; colour(7, None)
    print "here's a python script you can run: ", 
    print colour(11, None) + outname + colour(7, None)
print

 

there is no perfect language for coding

you can joke that x is “perfect” or that a language is close enough, but theres no such thing.

if i were to pick a perfect language, i would probably single out python. but its not the fastest, i dont like the direction its going in, its not the best language for low-level tasks like writing drivers or an operating system (youd probably want c for that) and its not even the best language for teaching first-time coders, but it does pretty well in that regard.

then theres fig. its designed for teaching, it addresses a number of things that make python less ideal sometimes, its heavily integrated with python (even allows inline python code and translates into python code) but its got tons of design decisions that are for a range of specific uses. i love using fig and i use it all the time, but its good for what its good for– it isnt perfect either.

one of the surest ways to improve (or ruin) a language is to try to make it perfect. people dont know (im not sure they can know) what “perfect” would be, but that doesnt stop them from trying. occasionally, that effort goes well. more often, it seems like they break more than they fix.

this is subjective of course, but thats really the point– the cons are subjective, but so are the pros. and so really no language can be “perfect.” people could never agree what that would even mean, and many notions of perfection are so impractical, they might as well be impossible.

the more elaborate your notion of quality is, the more work it takes to maintain it if you update it. the amount of work that will actually get done depends on the level of resources and interest towards that effort.

this is a highly variable thing, more than people seem to realize. they take for granted that monumental efforts require monumental interest– whether to volunteer time, or spend money, or both. and that level of interest can change any time the nature of the result changes.

some people clearly build large languages on the assumption that there will be substantial interest– at least their own. its difficult to predict the amount of interest even you will have in something in the future. im still very interested in fig, 2 years later. and ive been using python for most of a decade.

but if trends are easy to predict, no one is releasing much data on them– or almost no one is paying much attention to the data. if any language were perfect, the data probably wouldnt be as spread out as it is.

 

 

 

fig 4.2: (backwards compatibly) supports british and aussie spelling

t "hello" colortext 5 print

t "hello" colourtext 5 print

# both lines work; both are supported in help system

download on figs support forum: http://unofficialdistros.freeforums.org/fig-4-2-colortext-and-colourtext-both-valid-commands-t95.html

 

v sine (fig graphics)

vsine

 

#### license: creative commons cc0 1.0 (public domain)
#### http://creativecommons.org/publicdomain/zero/1.0/
proginf = "v sine 2017 mn"
function rgbcolour r g b c
python
    figcgapal[c] = (r, g, b)
    fig
    fig
v 1
c 400
w 3.14159 divby 2
for r 490 175 -.125
    e w minus 0.00413367105263 swap e w # 3.14159 / 4 / (490 - 300)
    for p -3.14159 3.14159 .003067958984375
        t w cos times 380 divby 2 int
        rc r divby 2.5 int
        rd 256 minus rc rgbcolour rc rc 32 11
        e w sin times t times 2 plus r plus 7 divby 5
        x p times 2 cos times e plus c int
        y p times 2 sin times e plus r minus 50  int
        m 6.28 plus 1.57 divby 108.503 divby 2
        now v plus m swap now v
        rc r divby 4 int mod 2
        iftrue rc
            now v int mod 2 times 11 pset x y now
            y2 y minus 1 pset x y2 now
            fig
        next
    now display
    next
now display lineinput

 

floral (fig graphics)

floral

 

#### license: creative commons cc0 1.0 (public domain) 
#### http://creativecommons.org/publicdomain/zero/1.0/ 

proginf "floral 2017 mn"

function rgbcolour r g b c
python
    figcgapal[c] = (r, g, b)
    fig
    fig

function qline c d e f g
    ## draw 4 lines, points go 2x2
    ## (cheap but avoids gaps)
    now line c d e f g
    d2 d plus 1
    f2 f plus 1
    now line c d2 e f2 g
    c2 c plus 1
    e2 e plus 1
    now line c2 d2 e2 f2 g
    now line c2 d e2 f g
    fig

while 
    rf randint 35 105 ## radius
    sf rf divby 2 int ## range of radius change
    xmin rf plus sf
    xmax xmin times -1 plus 800
    ymin rf plus sf
    ymax ymin times -1 plus 600
    pc randint 5 15      ## petal count
    xc randint xmin xmax ## horiz location
    yc randint ymin ymax ##  vert location
    while
        cr randint 32 248
        cg randint 32 248
        cb randint 32 248
        #fewer greens and dingy colors
        greenish cr plus cb minus cg times -1
        ifless greenish 0
            ifmore cr 160 
                break
                fig
            ifmore cg 160 
                break
                fig
            ifmore cb 160 
                break
                fig
            fig
        wend
    now display
    for p -3.14159 3.14159 0.00076698974609375 # 3.14159 / 2**12
        r p times pc sin times sf plus rf plus 7
        x p cos times r plus xc int
        y p sin times r plus yc int
        now line x y xc yc 15
        next
    for p -3.14159 3.14159 0.00076698974609375 # 3.14159 / 2**12
        r p times pc sin times sf plus rf
        x p cos times r plus xc int
        y p sin times r plus yc int
        now rgbcolour cr cg cb 14 qline x y xc yc 14
        next
    now display
    wend

now lineinput

 

 

gem seven (fig graphics)

gemseven

 

#### license: creative commons cc0 1.0 (public domain)
#### http://creativecommons.org/publicdomain/zero/1.0/
proginf = "gem seven 2017 mn"
function rgbcolour r g b c
python
    figcgapal[c] = (r, g, b)
    fig
    fig
v 1
c 400
w 3.14159 divby 2
xb
yb
for r 490 300 -.25
    e w minus 0.00413367105263 swap e w # 3.14159 / 4 / (490 - 300)
    for p 0 3.14159 0.44879857142857144 # 3.14159 / 7
        e w cos times 380 divby 2 int
        rc r divby 3 plus 40  int
        rd 256 minus rc rgbcolour rd rc 0 11
        x p times 2 cos times e plus c int
        y p times 2 sin times e plus r minus 50  int
        m 6.28 plus 1.57 divby 108.503 divby 2
        now v plus m swap now v
        rc r divby 4 int mod 2
        iftrue rc
            iftrue xb
                now v int mod 2 times 11 line xb yb x y now 
            else    
                now v int mod 2 times 11 pset x y now
                fig
            xb x
            yb y
            fig
        next
    now display
    next
now display lineinput