diff --git a/lslopt/lslcommon.py b/lslopt/lslcommon.py
index c21082d..ccb2942 100644
--- a/lslopt/lslcommon.py
+++ b/lslopt/lslcommon.py
@@ -15,6 +15,10 @@
# You should have received a copy of the GNU General Public License
# along with LSL PyOptimizer. If not, see .
+# Classes, functions and variables for use of all modules.
+
+import sys
+
# These types just wrap the Python types to make type() work on them.
# There are no ops defined on them or anything.
@@ -46,6 +50,13 @@ IsCalc = False
DataPath = ''
+# Language
+
+# These are hardcoded because additions or modifications imply
+# important changes to the code anyway.
+types = frozenset(('integer','float','string','key','vector',
+ 'quaternion','rotation','list'))
+
# Conversion of LSL types to Python types and vice versa.
PythonType2LSL = {int: 'integer', float: 'float',
@@ -55,3 +66,7 @@ PythonType2LSL = {int: 'integer', float: 'float',
LSLType2Python = {'integer':int, 'float':float,
'string':unicode, 'key':Key, 'vector':Vector,
'rotation':Quaternion, 'list':list}
+
+def warning(txt):
+ assert type(txt) == unicode
+ sys.stderr.write(u"WARNING: " + txt + u"\n")
diff --git a/lslopt/lslfoldconst.py b/lslopt/lslfoldconst.py
index f648c79..9e2bef5 100644
--- a/lslopt/lslfoldconst.py
+++ b/lslopt/lslfoldconst.py
@@ -18,11 +18,10 @@
# Constant folding and simplification of expressions and statements.
import lslcommon
-from lslcommon import Vector, Quaternion
+from lslcommon import Vector, Quaternion, warning
import lslfuncs
from lslfuncs import ZERO_VECTOR, ZERO_ROTATION
import math
-from lslparse import warning
from lslfuncopt import OptimizeFunc, OptimizeArgs, FuncOptSetup
diff --git a/lslopt/lslloadlib.py b/lslopt/lslloadlib.py
new file mode 100644
index 0000000..079abb0
--- /dev/null
+++ b/lslopt/lslloadlib.py
@@ -0,0 +1,230 @@
+# (C) Copyright 2015-2017 Sei Lisa. All rights reserved.
+#
+# This file is part of LSL PyOptimizer.
+#
+# LSL PyOptimizer 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.
+#
+# LSL PyOptimizer 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 LSL PyOptimizer. If not, see .
+
+# Load the builtins and function properties.
+
+import sys, re
+from lslcommon import types, warning, Vector, Quaternion
+import lslcommon, lslfuncs
+
+def LoadLibrary(builtins = None, seftable = None):
+ """Load builtins.txt and seftable.txt (or the given filenames) and return
+ a tuple with the events, constants and functions, each in a dict.
+ """
+
+ if builtins is None:
+ builtins = lslcommon.DataPath + 'builtins.txt'
+
+ if seftable is None:
+ seftable = lslcommon.DataPath + 'seftable.txt'
+
+ events = {}
+ constants = {}
+ functions = {}
+
+
+ # Library read code
+
+ parse_lin_re = re.compile(
+ r'^\s*([a-z]+)\s+'
+ r'([a-zA-Z_][a-zA-Z0-9_]*)\s*\(\s*('
+ r'[a-z]+\s+[a-zA-Z_][a-zA-Z0-9_]*'
+ r'(?:\s*,\s*[a-z]+\s+[a-zA-Z_][a-zA-Z0-9_]*)*'
+ r')?\s*\)\s*$'
+ r'|'
+ r'^\s*const\s+([a-z]+)'
+ r'\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*?)\s*$'
+ r'|'
+ r'^\s*(?:#.*|//.*)?$')
+ parse_arg_re = re.compile(r'^\s*([a-z]+)\s+[a-zA-Z_][a-zA-Z0-9_]*\s*$')
+ parse_num_re = re.compile(r'^\s*(-?(?=[0-9]|\.[0-9])[0-9]*((?:\.[0-9]*)?(?:[Ee][+-]?[0-9]+)?))\s*$')
+ parse_str_re = re.compile(ur'^"((?:[^"\\]|\\.)*)"$')
+
+ f = open(builtins, 'rb')
+ try:
+ linenum = 0
+ try:
+ ubuiltins = builtins.decode(sys.getfilesystemencoding())
+ except UnicodeDecodeError:
+ # This is just a guess at the filename encoding.
+ ubuiltins = builtins.decode('iso-8859-15')
+ while True:
+ linenum += 1
+ line = f.readline()
+ if not line: break
+ if line[-1] == '\n': line = line[:-1]
+ try:
+ uline = line.decode('utf8')
+ except UnicodeDecodeError:
+ warning(u"Bad Unicode in %s line %d" % (ubuiltins, linenum))
+ continue
+ match = parse_lin_re.search(line)
+ if not match:
+ warning(u"Syntax error in %s, line %d" % (ubuiltins, linenum))
+ continue
+ if match.group(1):
+ # event or function
+ typ = match.group(1)
+ if typ == 'quaternion':
+ typ = 'rotation'
+ if typ == 'void':
+ typ = None
+ elif typ != 'event' and typ not in types:
+ warning(u"Invalid type in %s, line %d: %s" % (ubuiltins, linenum, typ))
+ continue
+ args = []
+ arglist = match.group(3)
+ if arglist:
+ arglist = arglist.split(',')
+ bad = False
+ for arg in arglist:
+ argtyp = parse_arg_re.search(arg).group(1)
+ if argtyp not in types:
+ uargtyp = argtyp.decode('utf8')
+ warning(u"Invalid type in %s, line %d: %s" % (ubuiltins, linenum, uargtyp))
+ del uargtyp
+ bad = True
+ break
+ args.append(argtyp)
+ if bad:
+ continue
+ name = match.group(2)
+ if typ == 'event':
+ if name in events:
+ uname = name.decode('utf8')
+ warning(u"Event at line %d was already defined in %s, overwriting: %s" % (linenum, ubuiltins, uname))
+ del uname
+ events[name] = tuple(args)
+ else:
+ # Library functions go to the functions table. If
+ # they are implemented in lslfuncs.*, they get a
+ # reference to the implementation; otherwise None.
+ if name in functions:
+ uname = name.decode('utf8')
+ warning(u"Function at line %d was already defined in %s, overwriting: %s" % (linenum, ubuiltins, uname))
+ del uname
+ fn = getattr(lslfuncs, name, None)
+ functions[name] = {'Kind':'f', 'Type':typ, 'ParamTypes':args}
+ if fn is not None:
+ functions[name]['Fn'] = fn
+ elif match.group(4):
+ # constant
+ name = match.group(5)
+ if name in constants:
+ uname = name.decode('utf8')
+ warning(u"Global at line %d was already defined in %s, overwriting: %s" % (linenum, ubuiltins, uname))
+ del uname
+ typ = match.group(4)
+ if typ not in types:
+ utyp = typ.decode('utf8')
+ warning(u"Invalid type in %s, line %d: %s" % (ubuiltins, linenum, utyp))
+ del utyp
+ continue
+ if typ == 'quaternion':
+ typ = 'rotation'
+ value = match.group(6)
+ if typ == 'integer':
+ value = int(value, 0)
+ elif typ == 'float':
+ value = lslfuncs.F32(float(value))
+ elif typ == 'string':
+ value = value.decode('utf8')
+ if parse_str_re.search(value):
+ esc = False
+ tmp = value[1:-1]
+ value = u''
+ for c in tmp:
+ if esc:
+ if c == u'n':
+ c = u'\n'
+ elif c == u't':
+ c = u' '
+ value += c
+ esc = False
+ elif c == u'\\':
+ esc = True
+ else:
+ value += c
+ #if typ == 'key':
+ # value = Key(value)
+ else:
+ warning(u"Invalid string in %s line %d: %s" % (ubuiltins, linenum, uline))
+ value = None
+ elif typ == 'key':
+ warning(u"Key constants not supported in %s, line %d: %s" % (ubuiltins, linenum, uline))
+ value = None
+ elif typ in ('vector', 'rotation'):
+ try:
+ if value[0:1] != '<' or value[-1:] != '>':
+ raise ValueError
+ value = value[1:-1].split(',')
+ if len(value) != (3 if typ == 'vector' else 4):
+ raise ValueError
+ num = parse_num_re.search(value[0])
+ if not num:
+ raise ValueError
+ value[0] = lslfuncs.F32(float(num.group(1)))
+ num = parse_num_re.search(value[1])
+ if not num:
+ raise ValueError
+ value[1] = lslfuncs.F32(float(num.group(1)))
+ num = parse_num_re.search(value[2])
+ if not num:
+ raise ValueError
+ value[2] = lslfuncs.F32(float(num.group(1)))
+ if typ == 'vector':
+ value = Vector(value)
+ else:
+ num = parse_num_re.search(value[3])
+ if not num:
+ raise ValueError
+ value[3] = lslfuncs.F32(float(num.group(1)))
+ value = Quaternion(value)
+ except ValueError:
+ warning(u"Invalid vector/rotation syntax in %s line %d: %s" % (ubuiltins, linenum, uline))
+ else:
+ assert typ == 'list'
+ if value[0:1] != '[' or value[-1:] != ']':
+ warning(u"Invalid list value in %s, line %d: %s" % (ubuiltins, linenum, uline))
+ elif value[1:-1].strip() != '':
+ warning(u"Non-empty list constants not supported in %s, line %d: %s" % (ubuiltins, linenum, uline))
+ value = None
+ else:
+ value = []
+ if value is not None:
+ constants[name] = value
+
+ finally:
+ f.close()
+
+ # Load the side-effect-free table as well.
+ # TODO: Transform the SEF Table into a function properties table
+ # that includes domain data (min, max) and stability data
+ # (whether multiple successive calls return the same result)
+ f = open(seftable, 'rb')
+ try:
+ while True:
+ line = f.readline()
+ if line == '':
+ break
+ line = line.strip()
+ if line and line[0] != '#' and line in functions:
+ functions[line]['SEF'] = True
+ finally:
+ f.close()
+
+ return events, constants, functions
diff --git a/lslopt/lsloutput.py b/lslopt/lsloutput.py
index 4aca83d..7ef0abf 100644
--- a/lslopt/lsloutput.py
+++ b/lslopt/lsloutput.py
@@ -19,8 +19,7 @@
import lslfuncs
import lslcommon
-from lslcommon import Key, Vector, Quaternion
-from lslparse import warning
+from lslcommon import Key, Vector, Quaternion, warning
from math import copysign
class outscript(object):
diff --git a/lslopt/lslparse.py b/lslopt/lslparse.py
index a20ea6d..2e40cc7 100644
--- a/lslopt/lslparse.py
+++ b/lslopt/lslparse.py
@@ -20,18 +20,13 @@
# TODO: Add info to be able to propagate error position to the source.
-from lslcommon import Key, Vector, Quaternion
-import lslcommon
-import lslfuncs
-import sys, re
+from lslcommon import Key, Vector, Quaternion, types
+import lslcommon, lslfuncs
+import re
# Note this module was basically written from bottom to top, which may help
# reading it.
-def warning(txt):
- assert type(txt) == unicode
- sys.stderr.write(u"WARNING: " + txt + u"\n")
-
def isdigit(c):
return '0' <= c <= '9'
@@ -218,8 +213,7 @@ class parser(object):
'if', 'else', 'for', 'do', 'while', 'print', 'TRUE', 'FALSE'))
brkcont_keywords = frozenset(('break', 'continue'))
switch_keywords = frozenset(('switch', 'case', 'break', 'default'))
- types = frozenset(('integer','float','string','key','vector',
- 'quaternion','rotation','list'))
+
PythonType2LSLToken = {int:'INTEGER_VALUE', float:'FLOAT_VALUE',
unicode:'STRING_VALUE', Key:'KEY_VALUE', Vector:'VECTOR_VALUE',
Quaternion:'ROTATION_VALUE', list:'LIST_VALUE'}
@@ -366,7 +360,7 @@ class parser(object):
if not self.enableswitch and value:
self.keywords |= self.switch_keywords
elif self.enableswitch and not value:
- self.keywords = self.base_keywords
+ self.keywords = self.base_keywords.copy()
if self.breakcont:
self.keywords |= self.brkcont_keywords
@@ -377,7 +371,7 @@ class parser(object):
if not self.breakcont and value:
self.keywords |= self.brkcont_keywords
elif self.breakcont and not value:
- self.keywords = self.base_keywords
+ self.keywords = self.base_keywords.copy()
if self.enableswitch:
self.keywords |= self.switch_keywords
@@ -572,7 +566,7 @@ class parser(object):
# Got an identifier - check if it's a reserved word
if ident in self.keywords:
return (ident.upper(),)
- if ident in self.types:
+ if ident in types:
if ident == 'quaternion':
ident = 'rotation' # Normalize types
return ('TYPE',ident)
@@ -909,7 +903,7 @@ class parser(object):
self.expect('(')
self.NextToken()
expr = self.Parse_expression()
- if expr['t'] not in self.types:
+ if expr['t'] not in types:
raise EParseTypeMismatch(self) if expr['t'] is None else EParseUndefined(self)
self.expect(')')
self.NextToken()
@@ -1036,7 +1030,7 @@ list lazy_list_set(list L, integer i, list v)
self.NextToken()
expr = self.Parse_expression()
rtyp = expr['t']
- if rtyp not in self.types:
+ if rtyp not in types:
raise EParseTypeMismatch(self)
if typ in ('integer', 'float'):
# LSL admits integer *= float (go figger).
@@ -1215,9 +1209,9 @@ list lazy_list_set(list L, integer i, list v)
return {'nt':'FNCALL', 't':sym['Type'], 'name':fn, 'scope':0,
'ch':expr['ch']}
- if typ == 'list' and basetype in self.types \
+ if typ == 'list' and basetype in types \
or basetype in ('integer', 'float') and typ in ('integer', 'float', 'string') \
- or basetype == 'string' and typ in self.types \
+ or basetype == 'string' and typ in types \
or basetype == 'key' and typ in ('string', 'key') \
or basetype == 'vector' and typ in ('string', 'vector') \
or basetype == 'rotation' and typ in ('string', 'rotation') \
@@ -1288,7 +1282,7 @@ list lazy_list_set(list L, integer i, list v)
while self.tok[0] in ('+', '-'):
op = self.tok[0]
ltype = term['t']
- if op == '+' and ltype not in self.types \
+ if op == '+' and ltype not in types \
or op == '-' and ltype not in ('integer', 'float',
'vector', 'rotation'):
raise EParseTypeMismatch(self)
@@ -1300,7 +1294,7 @@ list lazy_list_set(list L, integer i, list v)
# doesn't seem necessary to check rtype. But there's the case
# where the first element is a list, where the types don't need to
# match but the second type must make sense.
- if op == '+' and rtype not in self.types:
+ if op == '+' and rtype not in types:
#or op == '-' and rtype not in ('integer', 'float',
# 'vector', 'rotation'):
raise EParseTypeMismatch(self)
@@ -1393,7 +1387,7 @@ list lazy_list_set(list L, integer i, list v)
while self.tok[0] in ('==', '!='):
op = self.tok[0]
ltype = comparison['t']
- if ltype not in self.types:
+ if ltype not in types:
raise EParseTypeMismatch(self)
self.NextToken()
rexpr = self.Parse_inequality()
@@ -1520,7 +1514,7 @@ list lazy_list_set(list L, integer i, list v)
except EParseTypeMismatch:
raise EParseFunctionMismatch(self)
elif expected_types is False: # don't accept void expressions
- if expr['t'] not in self.types:
+ if expr['t'] not in types:
raise EParseTypeMismatch(self)
idx += 1
ret.append(expr)
@@ -2526,12 +2520,24 @@ list lazy_list_set(list L, integer i, list v)
self.NextToken()
- def parse(self, script, options = (), filename = ''):
- """Parse the given stream with the given options.
+ def parse(self, script, options = (), filename = '', lib = None):
+ """Parse the given string with the given options.
+
+ If given, lib replaces the library passed in __init__.
+
+ filename is the filename of the current file, for error reporting.
+ '' means errors in this file won't include a filename.
+ #line directives change the filename.
This function also builds the temporary globals table.
"""
+ if lib is None:
+ lib = self.lib
+ self.events = lib[0]
+ self.constants = lib[1]
+ self.funclibrary = lib[2]
+
self.filename = filename
if type(script) is unicode:
@@ -2540,7 +2546,7 @@ list lazy_list_set(list L, integer i, list v)
self.script = script
self.length = len(script)
- self.keywords = self.base_keywords
+ self.keywords = self.base_keywords.copy()
self.labelcnt = 0
@@ -2704,218 +2710,23 @@ list lazy_list_set(list L, integer i, list v)
return treesymtab
- def parsefile(self, filename, options = set()):
- """Convenience function to parse a file"""
+ def parsefile(self, filename, options = set(), lib = None):
+ """Convenience function to parse a file rather than a string."""
f = open(filename, 'r')
try:
script = f.read()
finally:
f.close()
- return self.parse(script, options)
+ return self.parse(script, options, lib = lib)
- def __init__(self, builtins = None, seftable = None):
- """Reads the library."""
+ def __init__(self, lib = None):
+ """Initialization of library and lazy compilation.
- self.events = {}
- self.constants = {}
- self.funclibrary = {}
-
- if builtins is None:
- builtins = lslcommon.DataPath + 'builtins.txt'
-
- if seftable is None:
- seftable = lslcommon.DataPath + 'seftable.txt'
+ lib is a tuple of three dictionaries: events, constants and functions,
+ in the format returned by lslloadlib.LoadLibrary().
+ """
self.parse_directive_re = None
- # Library read code
-
- parse_lin_re = re.compile(
- r'^\s*([a-z]+)\s+'
- r'([a-zA-Z_][a-zA-Z0-9_]*)\s*\(\s*('
- r'[a-z]+\s+[a-zA-Z_][a-zA-Z0-9_]*'
- r'(?:\s*,\s*[a-z]+\s+[a-zA-Z_][a-zA-Z0-9_]*)*'
- r')?\s*\)\s*$'
- r'|'
- r'^\s*const\s+([a-z]+)'
- r'\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*?)\s*$'
- r'|'
- r'^\s*(?:#.*|//.*)?$')
- parse_arg_re = re.compile(r'^\s*([a-z]+)\s+[a-zA-Z_][a-zA-Z0-9_]*\s*$')
- parse_num_re = re.compile(r'^\s*(-?(?=[0-9]|\.[0-9])[0-9]*((?:\.[0-9]*)?(?:[Ee][+-]?[0-9]+)?))\s*$')
- parse_str_re = re.compile(ur'^"((?:[^"\\]|\\.)*)"$')
-
- f = open(builtins, 'rb')
- try:
- linenum = 0
- try:
- ubuiltins = builtins.decode(sys.getfilesystemencoding())
- except UnicodeDecodeError:
- # This is just a guess at the filename encoding.
- ubuiltins = builtins.decode('iso-8859-15')
- while True:
- linenum += 1
- line = f.readline()
- if not line: break
- if line[-1] == '\n': line = line[:-1]
- try:
- uline = line.decode('utf8')
- except UnicodeDecodeError:
- warning(u"Bad Unicode in %s line %d" % (ubuiltins, linenum))
- continue
- match = parse_lin_re.search(line)
- if not match:
- warning(u"Syntax error in %s, line %d" % (ubuiltins, linenum))
- continue
- if match.group(1):
- # event or function
- typ = match.group(1)
- if typ == 'quaternion':
- typ = 'rotation'
- if typ == 'void':
- typ = None
- elif typ != 'event' and typ not in self.types:
- warning(u"Invalid type in %s, line %d: %s" % (ubuiltins, linenum, typ))
- continue
- args = []
- arglist = match.group(3)
- if arglist:
- arglist = arglist.split(',')
- bad = False
- for arg in arglist:
- argtyp = parse_arg_re.search(arg).group(1)
- if argtyp not in self.types:
- uargtyp = argtyp.decode('utf8')
- warning(u"Invalid type in %s, line %d: %s" % (ubuiltins, linenum, uargtyp))
- del uargtyp
- bad = True
- break
- args.append(argtyp)
- if bad:
- continue
- name = match.group(2)
- if typ == 'event':
- if name in self.events:
- uname = name.decode('utf8')
- warning(u"Event at line %d was already defined in %s, overwriting: %s" % (linenum, ubuiltins, uname))
- del uname
- self.events[name] = tuple(args)
- else:
- # Library functions go to the functions table. If
- # they are implemented in lslfuncs.*, they get a
- # reference to the implementation; otherwise None.
- if name in self.funclibrary:
- uname = name.decode('utf8')
- warning(u"Function at line %d was already defined in %s, overwriting: %s" % (linenum, ubuiltins, uname))
- del uname
- fn = getattr(lslfuncs, name, None)
- self.funclibrary[name] = {'Kind':'f', 'Type':typ, 'ParamTypes':args}
- if fn is not None:
- self.funclibrary[name]['Fn'] = fn
- elif match.group(4):
- # constant
- name = match.group(5)
- if name in self.constants:
- uname = name.decode('utf8')
- warning(u"Global at line %d was already defined in %s, overwriting: %s" % (linenum, ubuiltins, uname))
- del uname
- typ = match.group(4)
- if typ not in self.types:
- utyp = typ.decode('utf8')
- warning(u"Invalid type in %s, line %d: %s" % (ubuiltins, linenum, utyp))
- del utyp
- continue
- if typ == 'quaternion':
- typ = 'rotation'
- value = match.group(6)
- if typ == 'integer':
- value = int(value, 0)
- elif typ == 'float':
- value = lslfuncs.F32(float(value))
- elif typ == 'string':
- value = value.decode('utf8')
- if parse_str_re.search(value):
- esc = False
- tmp = value[1:-1]
- value = u''
- for c in tmp:
- if esc:
- if c == u'n':
- c = u'\n'
- elif c == u't':
- c = u' '
- value += c
- esc = False
- elif c == u'\\':
- esc = True
- else:
- value += c
- #if typ == 'key':
- # value = Key(value)
- else:
- warning(u"Invalid string in %s line %d: %s" % (ubuiltins, linenum, uline))
- value = None
- elif typ == 'key':
- warning(u"Key constants not supported in %s, line %d: %s" % (ubuiltins, linenum, uline))
- value = None
- elif typ in ('vector', 'rotation'):
- try:
- if value[0:1] != '<' or value[-1:] != '>':
- raise ValueError
- value = value[1:-1].split(',')
- if len(value) != (3 if typ == 'vector' else 4):
- raise ValueError
- num = parse_num_re.search(value[0])
- if not num:
- raise ValueError
- value[0] = lslfuncs.F32(float(num.group(1)))
- num = parse_num_re.search(value[1])
- if not num:
- raise ValueError
- value[1] = lslfuncs.F32(float(num.group(1)))
- num = parse_num_re.search(value[2])
- if not num:
- raise ValueError
- value[2] = lslfuncs.F32(float(num.group(1)))
- if typ == 'vector':
- value = Vector(value)
- else:
- num = parse_num_re.search(value[3])
- if not num:
- raise ValueError
- value[3] = lslfuncs.F32(float(num.group(1)))
- value = Quaternion(value)
- except ValueError:
- warning(u"Invalid vector/rotation syntax in %s line %d: %s" % (ubuiltins, linenum, uline))
- else:
- assert typ == 'list'
- if value[0:1] != '[' or value[-1:] != ']':
- warning(u"Invalid list value in %s, line %d: %s" % (ubuiltins, linenum, uline))
- elif value[1:-1].strip() != '':
- warning(u"Non-empty list constants not supported in %s, line %d: %s" % (ubuiltins, linenum, uline))
- value = None
- else:
- value = []
- if value is not None:
- self.constants[name] = value
-
- finally:
- f.close()
-
- # Load the side-effect-free table as well.
- # TODO: Transform the SEF Table into a function properties table
- # that includes domain data (min, max) and possibly input
- # parameter transformations e.g.
- # llSensor(..., PI, ...) -> llSensor(..., 4, ...).
- f = open(seftable, 'rb')
- try:
- while True:
- line = f.readline()
- if line == '':
- break
- line = line.strip()
- if line and line[0] != '#' and line in self.funclibrary:
- self.funclibrary[line]['SEF'] = True
- finally:
- f.close()
+ self.lib = lib if lib is not None else ({}, {}, {})
diff --git a/main.py b/main.py
index e5a46cc..5f988d6 100755
--- a/main.py
+++ b/main.py
@@ -24,6 +24,7 @@ from lslopt.lsloutput import outscript
from lslopt.lsloptimizer import optimizer
import sys, os, getopt, re
import lslopt.lslcommon
+import lslopt.lslloadlib
VERSION = '0.2.1beta'
@@ -651,7 +652,8 @@ def main(argv):
if not preshow:
- p = parser(builtins, seftable)
+ lib = lslopt.lslloadlib.LoadLibrary(builtins, seftable)
+ p = parser(lib)
try:
ts = p.parse(script, options,
fname if fname != '-' else '')
diff --git a/testparser.py b/testparser.py
index f6e922f..5ec6af6 100644
--- a/testparser.py
+++ b/testparser.py
@@ -24,7 +24,7 @@ from lslopt.lslparse import parser,EParseSyntax,EParseUEOF,EParseAlreadyDefined,
EParseDuplicateLabel,EParseCantChangeState,EParseCodePathWithoutRet
from lslopt.lsloutput import outscript
from lslopt.lsloptimizer import optimizer
-from lslopt import lslfuncs
+from lslopt import lslfuncs, lslloadlib
import unittest
import os
import lslopt.lslcommon
@@ -34,13 +34,13 @@ class UnitTestCase(unittest.TestCase):
class Test01_LibraryLoader(UnitTestCase):
def test_coverage(self):
- parser(builtins='builtins-unittest.txt')
- parser()
+ parser(lslloadlib.LoadLibrary(builtins='builtins-unittest.txt'))
+ parser(lslloadlib.LoadLibrary())
class Test02_Parser(UnitTestCase):
def setUp(self):
- self.parser = parser()
+ self.parser = parser(lslloadlib.LoadLibrary())
self.outscript = outscript()
def test_coverage(self):
@@ -248,7 +248,7 @@ class Test02_Parser(UnitTestCase):
class Test03_Optimizer(UnitTestCase):
def setUp(self):
- self.parser = parser()
+ self.parser = parser(lslloadlib.LoadLibrary())
self.opt = optimizer()
self.outscript = outscript()