def intf_INCR(E): """An increment function. Will increment a value by adding 1. Will also try to add one to the value of a symbol (leaving nothing). Incrementing text will append an extra copy of the last letter of the original string. Lists increment by adding another copy of the last item.""" term = E.The.StackPop() if term.whatami == 'SYM': if E.symtab[term.val].whatami == 'VAL': # Needs a new object to break old refs links. v = objectifier.StackOB_VAL(E.symtab[term.val].val + 1) E.symtab[term.val] = v elif E.symtab[term.val].whatami == 'TXT': # Needs a new object to break old refs links. t = objectifier.StackOB_TXT(E.symtab[term.val].val + E.symtab[term.val].val[-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'LST': # Needs a new object to break old refs links. t = objectifier.StackOB_LST(E.symtab[term.val].val + [E.symtab[term.val].val[-1]]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'SYM': pass # This is not complete. Because it's hard. elif term.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(term.val + 1)) elif term.whatami == 'TXT': newseq = term.val + term.val[-1] E.The.StackPush(objectifier.StackOB_TXT(newseq)) elif term.whatami == 'LST': newseq = term.val + [term.val[-1]] # Orig. list + last item. E.The.StackPush(objectifier.StackOB_LST(newseq)) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), term])
def intf_DECR(E): """A decrement function. Will decrease a value by subracting 1. Will also try to subtract one from the value of a symbol (leaving nothing). Decrementing text will remove the last letter of the original string. Lists decrement by removing the last item.""" term = E.The.StackPop() if term.whatami == 'SYM': if E.symtab[term.val].whatami == 'VAL': # Needs a new object to break old refs links. v = objectifier.StackOB_VAL(E.symtab[term.val].val - 1) E.symtab[term.val] = v elif E.symtab[term.val].whatami == 'TXT': # Needs a new object to break old refs links. t = objectifier.StackOB_TXT(E.symtab[term.val].val[0:-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'LST': # Needs a new object to break old refs links. t = objectifier.StackOB_LST(E.symtab[term.val].val[0:-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'SYM': pass # This is not complete. Because it's hard. elif term.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(term.val - 1)) elif term.whatami == 'TXT': newseq = term.val[0:-1] E.The.StackPush(objectifier.StackOB_TXT(newseq)) elif term.whatami == 'LST': newseq = term.val[0:-1] E.The.StackPush(objectifier.StackOB_LST(newseq)) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), term])
def intf_PUT(E): """Takes list from v3 and a position from v2 and replaces the v3 item at v2 with the value of v1. This should also take a SYM of a list. If that is the case, the output should be nothing but the SYM should contain the updated list. If a LST is supplied as v3, then an updated list is returned.""" if not inc.VAL(E,2) or not inc.listlike(E,3): print("Input Error: put") print(intf_PUT.__doc__) return # Without doing much of anything. ob1= E.The.StackPop() # List or text. n= int(E.The.StackPop().val) # Position. ob3= E.The.StackPop() # List or text. oblen= len(ob3.val) if oblen < n: n= oblen-1 elif n < 1: n= 0 else: n-= 1 if ob3.whatami == "TXT": listified= list(ob3.val) # Python strings are immutable. listified[n]= ob1.val ob3= objectifier.StackOB_TXT( ''.join(listified) ) else: if ob3.whatami == "SYM": ref2= E.resolve_symbol(ob3) if hasattr(ref2,'whatami') and ref2.whatami == 'LST': ref2.val[n]= ob1 else: print("Confusion.") else: ob3.val[n]= ob1 E.The.StackPush(ob3)
def intf_TAILN(E): """Returns a list or substring made of the first v1 items of a list or string (respectively) at v2.""" if not inc.VAL(E,1) or not inc.listlike(E,2): print("Input Error: tailn") print(intf_TAILN.__doc__) return # Without doing much of anything. n= int(E.The.StackPop().val) # Position. ob2= E.The.StackPop() # List or text. if ob2.whatami == "TXT": out= objectifier.StackOB_TXT( ob2.val[-n:] ) else: out= objectifier.StackOB_LST( ob2.val[-n:] ) E.The.StackPush(out)
def intf_NAMES(E): """Takes a list or SYM of a list from v1 and if that list has a name component, they are extracted into a separate list as TXT objects. This can be used with `repl` and `decorate` to change the naming of items in a list. [100 .9784 .8591 .5798::jpy usd franc pound] |money sto |money money names 3 [''chf'' ''gbp''] repl decorate money -> [100 .9784 .8591 .5798::jpy usd chf gbp] """ if not inc.listlike(E,1): print("Input Error: names") print(intf_NAMES.__doc__) return # Without doing much of anything. lstob= E.The.StackPop() # List item. if lstob.whatami == "SYM": symkey= lstob.val lstob= E.symtab[symkey] if lstob.whatami == "LST": namelist= map(lambda x: objectifier.StackOB_TXT(x) , lstob.names) E.The.StackPush( objectifier.StackOB_LST(namelist))
def intf_REVLIST(E): """Takes a LST object from v1 and returns a LST object where the components of v1 are reversed in order. This allows for a descending sort with `sort reverse`.""" # Python text sorting= `''.join(sorted([n for n in s]))` if not inc.listlike(E,1): print("Input Error: revlist") print(intf_REVLIST.__doc__) return # Without doing much of anything. ob1= E.The.StackPop() # List or text. if ob1.whatami == "TXT": out= objectifier.StackOB_TXT( ob1.val[::-1] ) else: if ob1.val and len(ob1.val) > 0: #revedvals= [x.val for x in ob1.val] revedvals= ob1.val[:] revedvals.reverse() out= objectifier.StackOB_LST( revedvals) else: out= ob1 E.The.StackPush(out)
def intf_SORT(E): """Takes a LST object from v1 and returns a LST object where the components of v1 are sorted in ascending order. The items should all be TXT or VAL and of the same kind.""" # Python text sorting= `''.join(sorted([n for n in s]))` # Check out MIN and MAX to see how to resolve SYM objects. Not done here yet. if not inc.listlike(E,1): print("Input Error: sort") print(intf_SORT.__doc__) return # Without doing much of anything. ob1= E.The.StackPop() # List or text. if ob1.whatami == "TXT": out= objectifier.StackOB_TXT( ''.join(sorted([n for n in ob1.val])) ) else: if ob1.val and len(ob1.val) > 0: sortedvals= sorted([x.val for x in ob1.val]) sortedvals= [objectifier.StackOB_VAL(x) for x in sortedvals] out= objectifier.StackOB_LST( sortedvals ) else: out= ob1 E.The.StackPush(out)
def intf_REPL(E): """Takes a string or list object from v3 and a position from v2 and a replacement string or list object from v1 and replaces the portion of v3 starting at v2 with v1. If v2 is less than 1 or greater than the `len` of v3, the items are simply concatenated, v1+v3 and v3+v1 respectively. [5 10 16 21 25] 3 [15 20] -> [5 10 15 20 25] ''abcdefghi'' 4 ''XYZ'' repl -> ''abcXYZghi'' """ if ( ( not inc.VAL(E,2) or not inc.listlike(E,1) or not inc.listlike(E,3) ) or ( inc.TXT(E,1) != inc.TXT(E,3) ) ): # If types don't match. print("Input Error: repl") print(intf_REPL.__doc__) return # Without doing much of anything. ob1= E.The.StackPop() # Replacement text or list n= int(E.The.StackPop().val) # Position. ob3ob= E.The.StackPop() # Original list or text. outistxt= (ob3ob.val == "TXT") oblen= len(ob3ob.val) if oblen < n: ob3= ob3ob.val+ob1.val elif n < 1: ob3= ob1.val+ob3ob.val else: n-= 1 if outistxt: ob3= list(ob3ob.val) # Python strings are immutable. else: ob3= ob3ob.val start= ob3ob.val[0:n] plusmid= start + ob1.val ob3= plusmid if len(plusmid) < oblen: ob3+= ob3ob.val[len(plusmid):] if outistxt: outob= objectifier.StackOB_TXT( ''.join(plusmid) ) else: outob= objectifier.StackOB_LST( ob3 ) E.The.StackPush(outob)
def intf_GET(E): """Returns from v2 LST object the value of the list component whose position is specified by v1. `[1.1 2.2 3.3 4.4] 3 get -> 3.3` See GETN for specifying position by list name. """ if not inc.VAL(E,1) or not inc.listlike(E,2): print("Input Error: get") print(intf_GET.__doc__) return # Without doing much of anything. n= int(E.The.StackPop().val) # Position. ob2= E.The.StackPop() # List or text. oblen= len(ob2.val) if oblen < n: n= oblen-1 elif n < 1: n= 0 else: n-= 1 if ob2.whatami == "TXT": out= objectifier.StackOB_TXT( ob2.val[n] ) else: out= objectifier.StackOB_LST( ob2.val[n] ) E.The.StackPush(out)
def intf_SUB(E): """Substring or sublist. Takes a string or list object from v3 and a start position from v2 and an end position from v1 and returns the sub-string or sub-list (respectively) from v2 to v1. If v1 is less than v2, an empty string or list is returned. Any positional value less than 1 is treated as 1. Any positional value greater than the `len` of v3 will be treated as the `len` of v3. The positional values are inclusive such that if v2 is 2 and v3 is 4, both the 2nd (and 3rd) and 4th position items will be part of the returned sub-object. ''abcdefghijklmnopqrstuvwxyz'' 19 21 sub -> ''stu'' """ if not inc.VAL(E,1) or not inc.VAL(E,2) or not inc.listlike(E,3): print("Input Error: sub") print(intf_SUB.__doc__) return # Without doing much of anything. n2= int(E.The.StackPop().val) # End position. n1= int(E.The.StackPop().val) # Start position. ob3= E.The.StackPop() # List or text. oblen= len(ob3.val) if oblen < n1: n1= oblen-1 elif n1 < 1: n1= 0 else: n1-= 1 if oblen < n2: n2= oblen elif n2 < 1: n2= 0 else: pass # Ok. out= ob3.val[n1:n2] if ob3.whatami == "LST": out= objectifier.StackOB_LST( out ) elif ob3.whatami == "TXT": out= objectifier.StackOB_TXT( out ) E.The.StackPush(out)
def put_user_settings_in_a_var(self, E): fi = objectifier.StackOB_TXT(self.outfile) ca = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.camera[0]), objectifier.StackOB_VAL(self.camera[1]), objectifier.StackOB_VAL(self.camera[2]) ]) ca.names = ['x', 'y', 'z'] ta = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.target[0]), objectifier.StackOB_VAL(self.target[1]), objectifier.StackOB_VAL(self.target[2]) ]) ta.names = ['x', 'y', 'z'] op = objectifier.StackOB_VAL(self.opacity) fl = objectifier.StackOB_VAL(self.facelines) lw = objectifier.StackOB_VAL(self.vlinewidth) ms = objectifier.StackOB_VAL(self.vrefreshms) bx = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.vboxX), objectifier.StackOB_VAL(self.vboxY) ]) bx.names = ['x', 'y'] tr = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.vtranX), objectifier.StackOB_VAL(self.vtranY) ]) tr.names = ['x', 'y'] sc = objectifier.StackOB_LST([ objectifier.StackOB_VAL(self.vscaleX), objectifier.StackOB_VAL(self.vscaleY) ]) sc.names = ['x', 'y'] vw = objectifier.StackOB_LST([fi, ca, ta, op, fl, lw, ms, bx, tr, sc]) vw.names = ['fi', 'ca', 'ta', 'op', 'fl', 'lw', 'ms', 'bx', 'tr', 'sc'] E.symtab['vw'] = vw
def intf_MUL(E): """Item multiplication operator where the values are the focus. Compare to `:*` where lists are the focus. Valid inputs: SYM SYM + -> (resolve any SYMs and proceed again) VAL VAL * -> simple multiplication TXT VAL * -> replication of text into concatenated text, commutative input LST_of_VALs VAL * -> list of each list item multiplied by VAL, commutative input LST_of_VALs LST_of_VALs * -> pad smaller with 1 and multiply each ith pos If two lists are multiplied, the shorter one is padded with ones to match the other. In the case of two lists and both have list names, the longest list's are used. Examples: 2 2 * -> 4 2 [1 2 3] * -> [2 4 6] 31.831 |diameter sto |diameter |pi * -> 100.000035756 [pi pi pi] pi inv * -> [1 1 1] [1 2 3] 2 * -> [2 4 6] [1 2 3] [1 2] * -> [1 4 3] Pad the shorter list with ones. [2 2] [4 4 4::x y z] * -> [8 8 4]<x y z> [1 2] [1 2 3] * -> [1 4 3] 4 ''ha'' * -> ''hahahaha'' ''backwards'' -2 * -> ''sdrawkcabsdrawkcab'' """ if not ((inc.TXT(E, 1) and inc.VAL(E, 2)) or (inc.VAL(E, 1) and inc.TXT(E, 2)) or ((inc.VAL(E, 1) or inc.LST_of_VALs(E, 1)) and (inc.VAL(E, 2) or inc.LST_of_VALs(E, 2)))): print("Input Error: mul") print(intf_MUL.__doc__) return # Without doing much of anything. v2 = E.resolve_symbol(E.The.StackPop()) v1 = E.resolve_symbol(E.The.StackPop()) if v1.whatami == 'VAL' and v2.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(v1.val * v2.val)) elif v1.whatami == "TXT": if v2.val < 0: v1.val, v2.val = v1.val[::-1], v2.val * -1 # Do this for `neg`. E.The.StackPush(objectifier.StackOB_TXT(v1.val * int(v2.val))) elif v2.whatami == "TXT": if v1.val < 0: v2.val, v1.val = v2.val[::-1], v1.val * -1 # It's silly, I know. E.The.StackPush(objectifier.StackOB_TXT(v2.val * int(v1.val))) elif ((v1.whatami == 'LST' and v2.whatami == 'VAL') or (v1.whatami == 'VAL' and v2.whatami == 'LST')): # Mixed LST&VAL if v1.whatami == 'VAL': v1, v2 = v2, v1 # Ensure LST 1st then VAL 2nd outlist = list() for i in v1.val: if i.whatami == 'SYM': i = E.resolve_symbol(i) outlist.append(objectifier.StackOB_VAL(i.val * v2.val)) outlistob = objectifier.StackOB_LST(outlist) outlistob.names = v1.names[:] E.The.StackPush(outlistob) elif v1.whatami == 'LST' and v2.whatami == 'LST': lv1, lv2 = len(v1.val), len(v2.val) if lv1 < lv2: v1, v2 = v2, v1 # Longest LST first. lv1, lv2 = lv2, lv1 outlist = list() for n, i in enumerate(v1.val): if i.whatami == 'SYM': i = E.resolve_symbol(i) if n < lv2: if v2.val[n].whatami == 'SYM': froml2 = E.resolve_symbol(i) else: froml2 = v2.val[n] outlist.append(objectifier.StackOB_VAL(i.val * froml2.val)) else: outlist.append(objectifier.StackOB_VAL(i.val)) outlistob = objectifier.StackOB_LST(outlist) if not v1.names and v2.names: # If both have names go with v1's. v1, v2 = v2, v1 outlistob.names = v1.names[:] E.The.StackPush(outlistob) else: print( "Error: What the hell have you done!? This should never have happend. See `intf_MUL`." ) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), v2, v1])
def intf_ADD(E): """Item addition operator where the values are the focus. Compare to `:+` where lists are the focus. All SYMs are resolved. Valid inputs: TXT TXT + -> concatenate text VAL VAL + -> simple addition, commutative LST_of_VALs VAL + -> add VAL to all items in list (of values), commutative LST_of_VALs LST_of_VALs + -> pad smaller with zero and add each ith pos, commutative If two lists are added, the shorter one is padded with zeros to match the other. In the case of two lists and both have list names, the longest list's are used. Examples: 2 2 + -> 4 |pi pi + 2deg -> 360 [pi 10::a b] |Q sto -180 2rad Q.a + -> 0 [4 8] 3 + -> [7 11] [4 8] [2 3] + -> [6 11] [4 8] [2 3] + -> [6 11] [4 8 3] [2 3] + -> [6 11 3] [4 8] [1 2 3] + -> [5 10 3] [0 4] [1 2 3] + -> [1 6 3] [1 2 3::a b c] [2 2 2::x y z] + -> [3 4 5]<a b c> ''xed'' ''.ch'' + -> ''xed.ch'' """ if not ((inc.TXT(E, 1) and inc.TXT(E, 2)) or ((inc.VAL(E, 1) or inc.LST_of_VALs(E, 1)) and (inc.VAL(E, 2) or inc.LST_of_VALs(E, 2)))): print("Input Error: add") print(inc.LST_of_VALs(E, 1)) print(inc.LST_of_VALs(E, 2)) print(" Value 1:" + str(E.The.StackPop())) print(" Value 2:" + str(E.The.StackPop())) print(intf_ADD.__doc__) return # Without doing much of anything. v2 = E.resolve_symbol(E.The.StackPop()) v1 = E.resolve_symbol(E.The.StackPop()) if v1.whatami == 'TXT': # v2's been checked. E.The.StackPush(objectifier.StackOB_TXT(v1.val + v2.val)) elif v1.whatami == 'VAL' and v2.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(v1.val + v2.val)) elif ((v1.whatami == 'LST' and v2.whatami == 'VAL') or (v1.whatami == 'VAL' and v2.whatami == 'LST')): # Mixed LST&VAL if v1.whatami == 'VAL': v1, v2 = v2, v1 # Ensure LST 1st then VAL 2nd outlist = list() for i in v1.val: if i.whatami == 'SYM': i = E.resolve_symbol(i) outlist.append(objectifier.StackOB_VAL(i.val + v2.val)) outlistob = objectifier.StackOB_LST(outlist) outlistob.names = v1.names[:] E.The.StackPush(outlistob) elif v1.whatami == 'LST' and v2.whatami == 'LST': lv1, lv2 = len(v1.val), len(v2.val) if lv1 < lv2: v1, v2 = v2, v1 # Longest LST first. lv1, lv2 = lv2, lv1 outlist = list() for n, i in enumerate(v1.val): if i.whatami == 'SYM': i = E.resolve_symbol(i) if n < lv2: if v2.val[n].whatami == 'SYM': froml2 = E.resolve_symbol(i) else: froml2 = v2.val[n] outlist.append(objectifier.StackOB_VAL(i.val + froml2.val)) else: outlist.append(objectifier.StackOB_VAL(i.val)) outlistob = objectifier.StackOB_LST(outlist) if not v1.names and v2.names: # If both have names go with v1's. v1, v2 = v2, v1 outlistob.names = v1.names[:] E.The.StackPush(outlistob) else: print( "Error: What the hell have you done!? This should never have happend. See `intf_ADD`." ) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), v2, v1])