############################################################################# ## This file is part of Upgraded Variable Text Output Language. ## ##-------------------------------------------------------------------------## ## Copyright 2007-2008 Bryce Schroeder ## ## bryce.schroeder@gmail.com ## ## http://www.ferazelhosting.net/~bryce/ ## ## Contact me if you wish to use this program under other terms. ## ##-------------------------------------------------------------------------## ## This program is free software: you can redistribute it and/or modify ## ## it under the terms of the GNU General Public License as published by ## ## the Free Software Foundation, either version 3 of the License, or ## ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## ## along with this program. If not, see . ## ############################################################################# from .standard_interpreters import Resource, R from random import choice, randint from sys import argv, stdin, stdout, exit, stderr from os import environ class UVTOS(Resource): MANDATORY = ['text'] #OPTIONAL = ['meta'] def init(self): self.meta = {} if self.parts.has_key('meta'): self.meta = self.process_meta(self.parts['meta']) self.ns = {'NIL': ['']} if self.parts.has_key('library'): text, self.ns = evalvtos(self.parts['library'], self.ns) def __str__(self): return self.parts['text'] def evaluate(self): text, self.ns = evalvtos(self.parts['text'], self.ns) text = text.strip() if self['capitalize']: text = text.title() return text def __getitem__(self, key): return self.meta[key] # UVTOS SCRIPTING LANGUAGE SUPPORT # I wrote this code a LONG time ago... before I entered college # please be gentle to it :) ######## Library def number(call, ns): min, max = call[8:call.find(')')].split(',') min, max = int(min), int(max) return str(randint(min, max)) def enviro(call, ns): name = call[8:-1] return environ[name] def argument(call, ns): return argv[int(call[10:-1])] def python(call, ns): data = call[8:-1].replace('\\t', '\t').replace('\\n', '\n') exec data return '' def evaluate(call, ns): data = call[8:-1].replace('\\t', '\t').replace('\\n', '\n') return str(eval( data ) ) library = {'number':number,'enviro': enviro, 'argument':argument, 'python':python, 'evaluate': evaluate } ####### def safefind(text, character): i = 0 lent = len(text) intoken = 0 while i < lent: if text[i] == '[': intoken += 1 elif text[i] == ']': intoken -= 1 elif text[i] == '\\': i += 2 continue elif text[i] == character and not intoken: return i i += 1 return -1 def safesplit(text, character): i = 0 lent = len(text) intoken = 0 start = 0 lst = [] while i < lent: if text[i] == character and not intoken: lst.append(text[start:i]) start = i+1 elif text[i] == '\\': i += 2 continue elif text[i] == '[': intoken += 1 elif text[i] == ']': intoken -= 1 i += 1 lst.append(text[start:]) return lst def interpret_special(token, namespace): #May not be debugged. return library[token[1:safefind(token, '(')]](token, namespace) #return '' # Should have warning. def interpret_cast(token, namespace): vari, nset = safesplit(token[1:], ':') # should check to make sure lengths are same # or otherwise supress error. return namespace[nset][namespace[vari][0]] def interpret_composition(token, namespace): nset = [] name, list = safesplit(token[1:], ':') for set in safesplit(list, '|'): nset.extend(namespace[set]) namespace[name] = nset return '' def interpret_setdef(token, namespace): name, vals = safesplit(token,':') namespace[name] = safesplit(vals, '|') return '' def interpret_constdef(token, namespace): name, set = safesplit(token, ':') if set[0] == '?': echo = True set = set[1:] else: echo = False try: namespace[name] = (randint(0,len(namespace[set])-1), set) except: # should have a warning namespace[name] = (0,'NIL') if echo: return '' else: return '' if echo: return namespace[set][namespace[name][0]] else: return '' def interpret_anonset(token, namespace): return choice(safesplit(token, '|')) def interpret_recall(token, namespace): try: item = namespace[token] except: return '' # should have a warning if type(item) == tuple: return namespace[item[1]][item[0]] else: return choice(item) def interpret_token(text, namespace): if len(text) < 1: return '' # Should be a warning here. if text[0] == '!': return interpret_special(text, namespace) elif text[0] == '^': return interpret_cast(text, namespace) elif text[0] == '#': return '' # comment elif text[0] == '+': return interpret_composition(text, namespace) elif safefind(text, ':') != -1: if safefind(text, '|') != -1: return interpret_setdef(text, namespace) else: return interpret_constdef(text, namespace) else: if safefind(text, '|') != -1: return interpret_anonset(text, namespace) else: return interpret_recall(text, namespace) def make_pass(text, namespace): subs = 0 i = 0 intoken = 0 lent = len(text) out = '' while i < lent: if text[i] == '[': if not intoken: start = i+1 intoken += 1 elif text[i] == ']': intoken -= 1 if not intoken: subs += 1 out += interpret_token(text[start:i], namespace) elif text[i] == '\\': if not intoken: out += text[i:i+2] i += 2 continue elif not intoken: out += text[i] i += 1 if intoken != 0: stderr.write('Warning: Intokenation error. (%d)\n'%intoken) return out, subs # need to add warning about lose tokens. def evalvtos(text, ns={'NIL': ['']}): text = text.replace('\t', '').replace('\n', '') subs = 1 while subs: text, subs = make_pass(text, ns) return text.strip().replace('\\\\', '\0\0backslash\0\0').replace('\\n','\n').replace('\\t', '\t').replace('\\', '').replace('\0\0backslash\0\0', '\\')+'\n', ns