rev 567 - in trunk: . pr/test src
SVN User <[email protected]> Thu, 03 Jun 2004 17:31:06 -0400
| Newsgroups | gmane.comp.lang.prothon.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: mark
Date: 2004-06-03 17:30:56 -0400 (Thu, 03 Jun 2004)
New Revision: 567
Modified:
trunk/STATUS.txt
trunk/pr/test/test.pr
trunk/src/bytecodes.h
trunk/src/console.c
trunk/src/init.pth
trunk/src/interp.c
trunk/src/interp.h
trunk/src/object.c
trunk/src/parser_routines.c
trunk/src/prothon.y
trunk/src/sys.c
Log:
fixed stack problem with exceptions
Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/STATUS.txt 2004-06-03 21:30:56 UTC (rev 567)
@@ -5,6 +5,8 @@
--- GNU message catalog _"abc" strings
--- change all strings to resource file
+--- replace <NULL>, <objptr:1>, and <objptr:2> with noDefault_, argList_, and kwDict_
+
--- add resolution order combining prototypes and scope chains
--- Add properties methods: get_, set_, delete_
@@ -36,6 +38,8 @@
--- add support for APR_BINARY in File.c ('b' flag)
--- support any object that supports file methods in stdxxx (duck std)
+--- name_ and file_ (always absolute paths)
+
--- nesting /* .. */ comments
--- help() in interactive console()
Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/pr/test/test.pr 2004-06-03 21:30:56 UTC (rev 567)
@@ -1,14 +1,726 @@
#!/usr/bin/env prothon
-# imp.pr
+"""String format parser"""
-Sys.path.append!('../../pr/test')
-Sys.path.append!('../pr/test')
-print Sys.path
+import Re as _re
+/*
+import gettext as _gettext
+import os.path as _path
+try:
+ _MyDir, MyName = _path.split(__file__)
+except:
+ _MyDir = '.'
+_LocalsDir = _path.join(_MyDir, 'locals')
+_TextDomain = 'formatparser'
+_gettext.bindtextdomain(_TextDomain, _LocalsDir)
+_gettext.textdomain(_TextDomain)
+_ = _gettext.gettext
+*/
-import imp2
+# Exception types.
+object FPParseError(ParseError):
+ pass
-print imp2.attrs_
+object FPIndexError(IndexError):
+ pass
-imp2.func(99)
+object FPTypeError(TypeError):
+ pass
+object Tokenizer:
+ """Break a string into tokens"""
+
+ def makeFactory(re):
+ pat = _re.compile(re)
+ def Factory(s='', psn=0, next=''):
+ return self(pat, s, psn, next)
+ Factory.regex = re
+ return Factory{}
+
+ def init_(pat, s='', psn=0, next='', end=None):
+ self.pat = pat
+ self.s = s
+ if end is None:
+ self.end = s.len()
+ else:
+ self.end = end
+ self.psn = psn
+ self.next = next
+ self.rejected = False
+
+ def synchronize(other):
+ if not self is other:
+ self.s = other.s
+ self.psn = other.psn
+ self.end = other.end
+ self.next = other.next
+
+ def nextToken():
+ if self.rejected:
+ self.rejected = False
+ elif self.psn < self.end:
+ m = self.pat.search(self.s, self.psn)
+ if m is None:
+ self.next = ''
+ self.psn = self.end
+ else:
+ self.psn = m.end()
+ self.next = self.s[m.start():self.psn]
+
+ def reject():
+ self.rejected = True
+
+ def peekNextCh():
+ if self.psn is not None:
+ try:
+ return self.s[self.psn]
+ except IndexError:
+ self.psn = None
+ return ''
+
+ def skipCh():
+ self.psn += 1
+
+ def isEnd():
+ return self.psn >= self.end
+
+ def clear():
+ self.next = self.s = ''
+ self.psn = self.end = 0
+
+# Regular expression stuff
+# Please udate the break table if any changes made here.
+#
+# Find specifiers within a format string.
+RegEx = r"[^%]+"
+RootTokenizer = Tokenizer.makeFactory(RegEx)
+
+# Break a specifier into tokens.
+# A tokens is one of:
+# - "'" delimited string
+# - positive integer preceded by '@'
+# - character sequence starting with '%',
+# not containing break characters or white space,
+# and optionally ending with '%'
+# - character sequence not containing white space
+# or break characters
+# - break character
+# Tokens can be any break character,
+# a "'" delimited string, a positive integer
+# preceded by a "@", an name starting with,
+# and optionally ending with, a '%',
+# or any character sequence not containing
+# a break character or whitespace.
+RegEx = (r"'(''|[^'])*'|" +
+ r"@[0-9]+|" +
+ r"%[^-\s%(),.@:'!=><+*/]*%?|" +
+ r"[^-\s%(),.@:'!=><+*/]+|" +
+ r"==|!=|>=|<=|" +
+ r"[^\s]"
+ )
+FormatTokenizer = Tokenizer.makeFactory(RegEx)
+del RegEx
+
+# Reserved characters in a specifier.
+# These form a break table.
+# Please modify the regular expressions if any
+# changes made here.
+BreakChars = r"%(),.@:'!=><+-*/"
+
+ich = BreakChars.iter_()
+Escape = ich.next() # Marks special names at format level
+ArgListStart = ich.next() # Encloses function arguments
+ArgListEnd = ich.next()
+ArgSep = ich.next() # Separates function arguments
+AttribRefOp = ich.next() # References an anttribute
+PositionOp = ich.next() # Starts a position indentifier
+ExprLitOp = ich.next() # Leaves an expression unevaluated
+Quote = ich.next() # Delimits a character string
+# Arithmetic / comparison operator primitives
+NotSign = ich.next()
+EqualSign = ich.next()
+GreaterThanSign = ich.next()
+LessThanSign = ich.next()
+PlusSign = ich.next()
+MinusSign = ich.next()
+TimesSign = ich.next()
+DivideSign = ich.next()
+del ich
+
+# Arithmetic / comparison operators
+EqualOp = EqualSign + EqualSign
+NotEqualOp = NotSign + EqualSign
+GreaterThanOp = GreaterThanSign
+GreaterThanOrEqualOp = GreaterThanSign + EqualSign
+LessThanOp = LessThanSign
+LessThanOrEqualOp = LessThanSign + EqualSign
+AdditionOp = PlusSign
+SubtractionOp = MinusSign
+MultiplicationOp = TimesSign
+DivisionOp = DivideSign
+
+object Node:
+ """Abstract base type for parse tree node"""
+
+ # Abstract methods.
+ def parse(tokens):
+ """Abstract parse method"""
+ raise NameError #, \
+ #"parse required for " + String(type(self))
+
+ def eval(context=None):
+ """Abstract eval method"""
+ # Though most node subclasses implement eval, it is not required.
+ # Catch unintensional calls.
+ raise NameError #, \
+ #"eval not implemented for " + String(type(self))
+
+object Tree(Node):
+ """Abstract base type for none-leaf nodes"""
+
+ # Default methods.
+ def init_(tokens=None, parts=None):
+ if parts is None:
+ self.parts = []
+ else:
+ self.parts = list(parts)
+ self.parse(tokens)
+
+ def str_():
+ return ''.join([String(p) for p in self.iterParts()])
+
+ def addPart(part):
+ self.parts.append(part)
+
+ def iterParts(psn=0):
+ return iter(self.parts[psn:])
+
+ def getPart(idx):
+ return self.parts[idx]
+
+ def getParts(start):
+ return self.parts[start:]
+
+object String(Node):
+ """Wrap a string in a node-like object."""
+ def init_(s):
+ self.s = s
+
+ def eval(*args):
+ return self.s
+
+ def str_():
+ return self.s
+
+object QuotedString(String):
+ """A quoted string"""
+ def init_(tokens):
+ super.init_(tokens.next[1:-1].replace(Quote*2, Quote))
+ def str_():
+ return (Quote +
+ super.str_().replace(Quote, Quote*2) +
+ Quote)
+
+object Keyword(String):
+ """Keyword identifier node-like object"""
+ def init_(s):
+ super.init_(s)
+
+ def eval(context):
+ try:
+ obj = context.getObject(self.s)
+ except IndexError:
+ raise FPIndexError #, \
+ #fmt(_("Identifier %(s) not found"), s=self.s)
+ return obj
+
+ def getValue():
+ return self.s
+
+ def evalAttribute(obj, context):
+ return context.getAttribute(obj, self.s)
+
+EmptyKeywordInstance = Keyword('')
+
+object IntegerLiteral(Node):
+ """Wrap an integer in a node-like object"""
+ def init_(i):
+ self.i = i
+
+ def eval(*args):
+ return self.i
+
+ def str_():
+ return String(self.i)
+
+object ArgumentPosition(Node):
+ """Argument position node-like object"""
+ def init_(tokens):
+ self.p = int(tokens.next[1:])
+
+ def eval(context):
+ return context.getObjectIdx(self.p)
+
+ def str_():
+ return PositionOp + String(self.p)
+
+def Identifier(tokens):
+ """Return token as a node"""
+ ch = tokens.next[0]
+ if ch == PositionOp:
+ node = ArgumentPosition(tokens)
+ elif ch == Quote:
+ node = QuotedString(tokens)
+ elif ch == Escape:
+ node = Keyword(tokens.next)
+ elif ch in BreakChars:
+ node = EmptyKeywordInstance
+ tokens.reject()
+ else:
+ s = tokens.next
+ try:
+ node = IntegerLiteral(int(s))
+ except ValueError:
+ node = Keyword(s)
+ return node
+
+# Accepts node in parts. Leaves token in next if any.
+object References(Tree):
+ """Reference an identifier"""
+
+ def parse(tokens):
+ while tokens.next == AttribRefOp:
+ tokens.nextToken()
+ if tokens.isEnd():
+ raise FPParseError #, \
+ #_("Reference missing attribute keyword.")
+ node = Identifier(tokens)
+ if not isinstance(node, Keyword):
+ raise FPParseError #, \
+ #fmt(_("Require a keyword for attribute name: got '%(n)'"),
+ # n=node)
+ if node is EmptyKeywordInstance:
+ raise FPParseError #, \
+ #_("Require an attribute name: got nothing")
+ tokens.nextToken()
+ if tokens.next == ArgListStart:
+ self.addPart(FunctionCall(tokens, [node]))
+ tokens.nextToken()
+ else:
+ self.addPart(node)
+
+ def eval(context):
+ value = self.getPart(0).eval(context)
+ for attr in self.iterParts(1):
+ value = attr.evalAttribute(value, context)
+ return value
+
+ def str_():
+ return AttribRefOp.join([String(p) for p in self.iterParts()])
+
+object ExpressionClosure:
+ def init_(expr, context):
+ self.expr = expr
+ self.context = context
+
+ def getValue():
+ return self.expr.eval(self.context)
+
+ def str_():
+ return String(self.expr)
+
+# Accepts nothing. Leaves token in next, if any.
+object ExpressionLiteral(Tree):
+ def parse(tokens):
+ tokens.nextToken()
+ if tokens.next == '':
+ raise FPParseError #, \
+ #_("Expecting an expression after a literal op.: got nothing")
+ self.addPart(QuotedExpression(tokens))
+
+ def eval(context):
+ return ExpressionClosure(self.getPart(0), context)
+
+ def str_():
+ return ExprLitOp + String(self.getPart(0))
+
+object Negate(Node):
+ def init_(node):
+ self._node = node
+ def eval(context):
+ return context.doMethod(self._node.eval(context), '_minus_')
+ def str_():
+ return '-' + String(self._node)
+
+# Accepts token in tokens. Leaves token in next, if any.
+def FullIdentifier(tokens):
+ if tokens.next == SubtractionOp:
+ tokens.nextToken()
+ if tokens.next is '':
+ raise FPParseError #, \
+ #_("Unexpected end-of-negation op.")
+ node = FullIdentifier(tokens)
+ if node is EmptyKeywordInstance:
+ raise FPParseError #, \
+ #_("Expected identifier after negation op.")
+ node = Negate(node)
+ else:
+ node = Identifier(tokens)
+ tokens.nextToken()
+ if tokens.next == ArgListStart:
+ node = FunctionCall(tokens, [node])
+ tokens.nextToken()
+ if tokens.next == AttribRefOp:
+ node = References(tokens, [node])
+ return node
+
+object BinaryOperator(Node):
+ # To be defined by subclasses
+ Op = ''
+ Method = ''
+ def getNode():
+ raise NameError #, \
+ #("BinaryOperator attribute getNode missing for %s" %
+ # type(self))
+
+ def init_(tokens, left, getNode):
+ if left is EmptyKeywordInstance:
+ raise FPParseError #, \
+ #fmt(_("Expecting an expression before '%(s)' op."),
+ # s=self.Op)
+ self._left = left
+ tokens.nextToken()
+ if tokens.next == '':
+ raise FPParseError #, \
+ #fmt(_("Unexpected end of '%(s)' expression"),
+ # s=self.Op)
+ right = getNode(tokens)
+ if right is EmptyKeywordInstance:
+ raise FPParseError#, \
+ #fmt(_("Expecting an expression after '%(s)' op."),
+ # s=self.Op)
+ self._right = right
+
+ def eval(context):
+ return context.doMethod(self._left.eval(context),
+ self.Method,
+ self._right.eval(context))
+
+ def str_():
+ return "%s %s %s" % (self._left, self.Op, self._right)
+
+object Divide(BinaryOperator):
+ Op = DivisionOp
+ Method = '_div_'
+
+object Multiply(BinaryOperator):
+ Op = MultiplicationOp
+ Method = '_mult_'
+
+# Accepts token in tokens. Leaves token in next, if any.
+def Multiplication(tokens):
+ node = FullIdentifier(tokens)
+ cont = True
+ while cont:
+ if tokens.next == MultiplicationOp:
+ node = Multiply(tokens, node, FullIdentifier)
+ elif tokens.next == DivisionOp:
+ node = Divide(tokens, node, FullIdentifier)
+ else:
+ cont = False
+ return node
+
+object Subtract(BinaryOperator):
+ Op = SubtractionOp
+ Method = '_sub_'
+
+object Add(BinaryOperator):
+ Op = AdditionOp
+ Method = '_add_'
+
+# Accepts token in tokens. Leaves token in next, if any.
+def Addition(tokens):
+ node = Multiplication(tokens)
+ cont = True
+ while cont:
+ if tokens.next == AdditionOp:
+ node = Add(tokens, node, Multiplication)
+ elif tokens.next == SubtractionOp:
+ node = Subtract(tokens, node, Multiplication)
+ else:
+ cont = False
+ return node
+
+object IsLessThanOrEqual(BinaryOperator):
+ Op = LessThanOrEqualOp
+ Method = '_le_'
+
+object IsLessThan(BinaryOperator):
+ Op = LessThanOp
+ Method = '_lt_'
+
+object IsGreaterThanOrEqual(BinaryOperator):
+ Op = GreaterThanOrEqualOp
+ Method = '_ge_'
+
+object IsGreaterThan(BinaryOperator):
+ Op = GreaterThanOp
+ Method = '_gt_'
+
+object IsNotEqual(BinaryOperator):
+ Op = NotEqualOp
+ Method = '_ne_'
+
+# Accepts node; returns token in next.
+object IsEqual(BinaryOperator):
+ Op = EqualOp
+ Method = '_eq_'
+
+# Accepts token in tokens. Leaves token in next, if any.
+def Comparison(tokens):
+ node = Addition(tokens)
+ if tokens.next == EqualOp:
+ node = IsEqual(tokens, node, Addition)
+ elif tokens.next == NotEqualOp:
+ node = IsNotEqual(tokens, node, Addition)
+ elif tokens.next == GreaterThanOp:
+ node = IsGreaterThan(tokens, node, Addition)
+ elif tokens.next == GreaterThanOrEqualOp:
+ node = IsGreaterThanOrEqual(tokens, node, Addition)
+ elif tokens.next == LessThanOp:
+ node = IsLessThan(tokens, node, Addition)
+ elif tokens.next == LessThanOrEqualOp:
+ node = IsLessThanOrEqual(tokens, node, Addition)
+ return node
+
+# Accepts token in tokens. Leaves token in next, if any.
+def QuotedExpression(tokens):
+ """Reference an identifier"""
+ if tokens.next == ExprLitOp:
+ node = ExpressionLiteral(tokens)
+ else:
+ node = Comparison(tokens)
+ return node
+
+# Accepts node in parts; ignores token in tokens;
+# leaves ArgListEnd in tokens.
+object FunctionCall(Tree):
+ """Call a function"""
+ def parse(tokens):
+ if not isinstance(self.getPart(0), Keyword):
+ raise FPParseError #, \
+ #fmt(_("Function call requires keyword: got %(s)"),
+ # s=self.getPart(0))
+ while True:
+ tokens.nextToken()
+ if tokens.next == '':
+ raise FPParseError #, _("Unexpected end of arg. list")
+ node = QuotedExpression(tokens)
+ if not tokens.next:
+ raise FPParseError #, _("Unexpected end of arg. list")
+ if tokens.next == ArgListEnd: # Loop test
+ break
+ if tokens.next == ArgSep:
+ self.addPart(node)
+ else:
+ raise FPParseError #, \
+ #fmt(_("Unexpected character %(c) in argument list"),
+ # c=tokens.next[0])
+ if node is not EmptyKeywordInstance:
+ self.addPart(node)
+
+ def eval(context):
+ return context.doFunction(self.getPart(0).getValue(),
+ *[arg.eval(context) for arg in self.iterParts(1)])
+
+ def evalAttribute(obj, context):
+ return context.doMethod(obj, self.getPart(0).getValue(),
+ *[arg.eval(context) for arg in self.iterParts(1)])
+
+ def str_():
+ if self.getPart(-1) is EmptyKeywordInstance:
+ term=ArgSep
+ else:
+ term=''
+ return ("%s(%s%s)" %
+ (String(self.getPart(0)),
+ ArgSep.join([String(p) for p in self.iterParts(1)]),
+ term))
+
+SpecifierTokens = FormatTokenizer() # Share with subtree node
+
+def Specifier(tokens):
+ """Parse a single format specifier"""
+ SpecifierTokens.synchronize(tokens)
+ SpecifierTokens.nextToken()
+ node = Identifier(SpecifierTokens)
+ if SpecifierTokens.next == Escape or SpecifierTokens.next[-1] != Escape:
+ SpecifierTokens.nextToken()
+ if SpecifierTokens.next == ArgListStart:
+ node = FunctionCall(SpecifierTokens, [node])
+ else:
+ raise FPParseError #, "Format specification missing arg. list."
+ tokens.synchronize(SpecifierTokens)
+ return node
+
+gen iterFormat(s):
+ """Iterate over the specifier and non-specifier parts
+ of a format."""
+ tokens = RootTokenizer(s)
+ while not tokens.isEnd():
+ if tokens.peekNextCh() == Escape:
+ yield Specifier(tokens)
+ else:
+ tokens.nextToken()
+ yield String(tokens.next)
+
+object Context:
+ """Execution environment of a specifier"""
+
+ def init_(next, namedobjs=None, funcs=None, idxobjs=None):
+ self._nxtgetObject = next.getObject
+ if namedobjs is None or namedobjs.len() == 0: # None or empty map
+ self._namedobjects = None
+ self.getObject = next.getObject
+ else:
+ print "mch", namedobjs
+ self._namedobjects = Dict(namedobjs)
+ self._nxtdoFunction = next.doFunction
+ if not funcs: # None or empty map
+ self._functions = None
+ self.doFunction = next.doFunction
+ else:
+ self._functions = Dict(funcs)
+ self._nxtgetObjectIdx = next.getObjectIdx
+ if not idxobjs:
+ self._indexedobjects = None
+ self.getObjectIdx = next.getObjectIdx
+ else:
+ self._indexedobjects = Tuple(idxobjs)
+ self.getAttribute = next.getAttribute
+ self.doMethod = next.doMethod
+
+ # Default context interface methods;
+ # may be overridden by instance versions.
+ def getObject(name):
+ try:
+ obj = self._namedobjects[name]
+ except IndexError:
+ obj = self._nxtgetObject(name)
+ return obj
+
+ def getObjectIdx(idx):
+ try:
+ obj = self._indexedobjects[idx]
+ except IndexError:
+ obj = self._nxtgetObjectIdx(idx)
+ return obj
+
+ def doFunction(name, *args):
+ try:
+ fn = self._functions[name]
+ except IndexError:
+ return self._nxtdoFunction(name, *args)
+ return fn(*args)
+
+# Foratter for internal user.
+object SimpleFormatter:
+
+ def init_(map=None):
+ self._recurselevel = 0
+ if map is None:
+ self._map = {}
+ else:
+ self._map = dict(map)
+ self._map.update!({Escape: self._doFormat,
+ '':None,
+ Escape*2:Escape,
+ '%sn%s' % (Escape, Escape): '\n'})
+
+ def call_(*args, **kwds):
+ """(fmt, id1=arg1, id2=arg2, ...) ==> string."""
+ if self._recurselevel > 1:
+ # We have a problem.
+ return "fmt: %s\n" +
+ "args: %s\n" +
+ "kwds: %s\n" % (repr(args[0]), String(args[1:]), String(kwds))
+ try:
+ fmt = args[0]
+ except IndexError:
+ raise FMTTypeError #, \
+ #fmt(_("Formatter() takes at least 1 argument (%(n) given)"),
+ # n=args.len()
+ try:
+ for idx, arg in enumerate(args[1:]):
+ kwds[idx] = arg
+ except NameError:
+ for idx in args.len()-1:
+ kwds[idx] = args[idx+1]
+# for idx, arg in zip(range(args.len()-1), args[1:]):
+# kwds[idx] = arg
+ # Join upgrades to unicode if one of the
+ # sequence items is unicode.
+ context = self.newContext(kwds)
+ self._recurselevel += 1
+ try:
+ return ''.join([f.eval(context) for f in iterFormat(fmt)])
+ finally:
+ self._recurselevel -= 1
+
+ # Context interface.
+ def newContext(namedobjs=None, funcs=None, idxobjs=None):
+ return Context(self, namedobjs, funcs, idxobjs)
+
+ def getObject(obj):
+ return self._map[obj]
+
+ def getObjectIdx(idx):
+ raise IndexError #, \
+ #fmt(_("Argument index @%(i) out-of-range"), i=idx)
+
+ def getAttribute(obj, attr):
+ if attr == 'type':
+ return type(obj)
+ if attr == 'str':
+ return String(obj)
+ if attr == 'unicode':
+ return unicode(obj)
+ if attr == 'repr':
+ return repr(obj)
+ raise NameError #, \
+ #fmt(_("Unsupported attribute %(attr)"), attr=attr)
+ return '' # Never gets here
+
+ def doFunction(name, *args):
+ return self._map[name](*args)
+
+ def doMethod(obj, attr, *args):
+ if attr == 'center':
+ if isinstance(obj, unicode):
+ return obj.center(args[0])
+ return String(obj).center(args[0])
+ raise NameError #, \
+ #fmt(_("Unsupported method %(attr)"), attr=attr)
+ return '' # Never gets here
+
+ def close():
+ pass
+
+ # Formatting function.
+ def _doFormat(obj, width=None, precision=None):
+ s = String(obj)
+ if not precision:
+ if not width:
+ return s
+ return "%*s" % (width, s)
+ if not width:
+ return "%.*s" % (precision, s)
+ return "%*.*s" % (width, precision, s)
+
+object fmt(SimpleFormatter): pass
+fmt.init_()
+
+print "Starting test now"
+print fmt("Version 0.4.3")
+print fmt("The value of pi to %(p) decimal places is %(pi,,p) .",
+ pi=3.141592658, p=4)
\ No newline at end of file
Modified: trunk/src/bytecodes.h
===================================================================
--- trunk/src/bytecodes.h 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/bytecodes.h 2004-06-03 21:30:56 UTC (rev 567)
@@ -223,6 +223,13 @@
/********/ OP_TWO_WORDS_BOUNDARY, /********/
+// CLRSP
+// clear sp
+// stack: -> <empty>
+// param: <unused>
+// |opcode|
+OP_CLRSP,
+
// POP
// delete top-of-stack
// param: words to pop
@@ -243,13 +250,6 @@
// |opcode|
OP_DUPLICATE,
-// SAVE_TMP
-// save top-of-stack in temporary register
-// stack: item -> <empty>
-// param: <unused>
-// |opcode|
-OP_SAVE_TMP,
-
// RESTORE_TMP
// push temporary register onto stack
// stack: <empty> -> item
Modified: trunk/src/console.c
===================================================================
--- trunk/src/console.c 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/console.c 2004-06-03 21:30:56 UTC (rev 567)
@@ -189,7 +189,7 @@
new_self = new_object(ist, NULL);
if (!ist->frame) {
new_locals = NEW_OBJ(NULL);
- frame = create_frame(ist, new_self, NULL, NULL, new_locals, NULL, NULL);
+ frame = create_frame(ist, new_self, NULL, NULL, new_locals, NULL, NULL, "console");
}
if ((home = getenv("HOME")) != NULL)
Modified: trunk/src/init.pth
===================================================================
--- trunk/src/init.pth 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/init.pth 2004-06-03 21:30:56 UTC (rev 567)
@@ -12,7 +12,7 @@
c:\prothon\modules\OS\debug
c:\prothon\modules\DBM\debug
-# this is executed before Main1 as module PthMod1
+# this is executed before Main as module PthMod1
-#import Re,File
+import File
Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/interp.c 2004-06-03 21:30:56 UTC (rev 567)
@@ -102,7 +102,7 @@
//******************************** create_frame *****************************
frame_p create_frame( isp ist, obj_p self, obj_p syn_locals, obj_p dyn_locals,
- obj_p locals, obj_p func_obj, code_p code_in ) {
+ obj_p locals, obj_p func_obj, code_p code_in, char* name ) {
obj_p prev_scope;
frame_p frame;
code_p code = NULL;
@@ -113,7 +113,13 @@
frame = pr_malloc(flen);
memset(frame, 0, flen);
- if (func_obj) frame->func = func_obj;
+ frame->func_name = name;
+ if (func_obj) {
+ obj_p name_obj;
+ frame->func = func_obj;
+ if (name_obj = get_attr(ist, func_obj, SYM(NAME_)))
+ frame->func_name = as_str(ist, name_obj);
+ }
frame->self = self;
frame->dyn_locals = dyn_locals;
frame->locals = locals;
@@ -125,7 +131,8 @@
if (!prev_scope && syn_locals) prev_scope = syn_locals;
if (prev_scope)
set_attr(ist, frame->locals, SYM(PREVSCOPE_), prev_scope);
-
+ if (!frame->func_name)
+ flen = 1;
return frame;
}
@@ -735,9 +742,13 @@
frame_p *switch_frame, frame_p *free_frame, obj_p return_value ){
obj_p res = NULL;
if (fr_prev) {
+ if (ist->exception_obj) {
+ fr_sp = 0;
+ fr_push(OBJ(NONE));
+ }
if (fr_pc == fr_code->len && fr_sp == 0)
fr_push(OBJ(NONE));
- if (fr_sp != 1){
+ if (fr_sp != 1) {
raise_exception(ist, OBJ(INTERNAL_EXC), "stack != 1 at return call");
return NULL;
}
@@ -814,7 +825,7 @@
#ifdef TRACE_INTERPRETER
if (trace_interpreter) {
if (!tfout) tfout = fopen("!code_trace.txt", "w");
- fprintf(tfout, "--- starting exec_loop at frame %8x, pc: %d\n", (intptr_t) frame, frame->pc);
+ fprintf(tfout, "--- starting exec_loop at frame %8x, pc: %d, %s\n", (intptr_t) frame, frame->pc, frame->func_name);
fflush(tfout);
}
#endif
@@ -867,16 +878,13 @@
switch (op) {
case OP_NOP:
break;
+ case OP_CLRSP:
+ fr_sp = 0;
+ break;
case OP_PUSH:
for(i=1; i < param; i++)
fr_push(fr_data(i));
break;
- case OP_SAVE_TMP:
- temp = fr_pop;
- break;
- case OP_RESTORE_TMP:
- fr_push(temp);
- break;
case OP_DUPLICATE: {
obj_p tmp = fr_stack[fr_sp+param];
fr_push(tmp);
@@ -1056,7 +1064,7 @@
if (op == OP_GEN) {
frame_p new_frame = create_frame( ist, frame->self, NULL,
frame->dyn_locals, frame->locals,
- func, NULL );
+ func, NULL, NULL );
new_frame->gen_marker = TRUE;
func->data.ptr = NULL;
switch_proto(ist, func, OBJ(GEN_PROTO));
@@ -1125,8 +1133,10 @@
case OP_RERAISE:
ist->exception_obj = exc_waiting;
exc_waiting = 0;
- if (exc_final_return)
+ if (exc_final_return) {
fr_pc = exc_final_return;
+ fr_sp = 0;
+ }
break;
case OP_EXEC: {
parse_state* state;
@@ -1141,7 +1151,7 @@
state = parse_file_or_string(ist, NULL, pr_strptr(str_obj));
if (!state || !(code = (state->parse_results))) break;
new_frame = create_frame( ist, frame->self, frame->syn_locals, frame->dyn_locals,
- frame->locals, NULL, code );
+ frame->locals, NULL, code, "execString" );
new_frame->syn_locals = frame->syn_locals;
new_frame->prev_frame = frame;
frame->next_frame = new_frame;
@@ -1205,7 +1215,7 @@
}
IF_EXC_BREAK;
new_frame = create_frame( ist, self, NULL, frame->locals,
- new_locals, func_obj, NULL );
+ new_locals, func_obj, NULL, NULL );
fr_next = new_frame;
new_frame->prev_frame = frame;
load_frame_params(ist, new_locals, func_obj, param*2, fr_stack+fr_sp+2);
@@ -1286,7 +1296,7 @@
#endif
fr_sp--;
switch_frame = create_frame( ist, frame->self, frame->locals, frame->dyn_locals,
- fr_stack[fr_sp], fr_data(1), NULL );
+ fr_stack[fr_sp], fr_data(1), NULL, "with" );
switch_frame->prev_frame = frame;
frame->next_frame = switch_frame;
end_op_obj: break;
@@ -1387,7 +1397,7 @@
}
IF_EXC_BREAK;
new_frame = create_frame( ist, self, NULL, frame->locals,
- new_locals, func_obj, NULL );
+ new_locals, func_obj, NULL, NULL );
fr_next = new_frame;
new_frame->prev_frame = frame;
load_frame_params(ist, new_locals, func_obj, param*2, fr_stack+fr_sp+3);
@@ -1539,7 +1549,7 @@
#ifdef TRACE_INTERPRETER
if (trace_interpreter) {
fprintf(tfout, "--- delete top frame %8x\n", (intptr_t) tmp_frame);
- fprintf(tfout, "--- new top frame is %8x\n", (intptr_t) frame);
+ fprintf(tfout, "--- new top frame is %8x, %s\n", (intptr_t) frame, frame->func_name);
fflush(tfout);
}
#endif
@@ -1584,7 +1594,7 @@
#ifdef TRACE_INTERPRETER
if (trace_interpreter) {
if (frame != DONE_FRAME_FLAG)
- fprintf(tfout, "--- switch to frame %8x\n", (intptr_t) frame);
+ fprintf(tfout, "--- switch to frame %8x, %s\n", (intptr_t) frame, frame->func_name);
fflush(tfout);
}
#endif
@@ -1666,7 +1676,7 @@
if (! (aself = get_attr(ist, func_obj, SYM(BINDOBJ_))) )
aself = self; if_exc_return 0;
new_frame = create_frame( ist, aself, NULL, NULL,
- new_locals, func_obj, NULL );
+ new_locals, func_obj, NULL, NULL );
new_frame->called_from_c = TRUE;
ist->frame->next_frame = new_frame;
new_frame->prev_frame = ist->frame;
@@ -1754,19 +1764,19 @@
if (framep && *framep) {
frame = *framep;
new_frame = create_frame( ist, frame->self, frame->syn_locals, frame->dyn_locals,
- frame->locals, NULL, code );
+ frame->locals, NULL, code, "execString" );
pr_free(*framep);
frame = NULL;
} else {
frame = ist->frame;
if (frame)
new_frame = create_frame( ist, frame->self, frame->syn_locals, frame->dyn_locals,
- frame->locals, NULL, code );
+ frame->locals, NULL, code, "execString" );
else {
obj_p new_globals = NEW_OBJ(NULL);
new_locals = NEW_OBJ(NULL);
new_frame = create_frame( ist, new_globals, new_locals, new_locals,
- new_locals, NULL, code );
+ new_locals, NULL, code, "execString" );
}
}
new_frame->called_from_c = TRUE;
@@ -1785,7 +1795,7 @@
obj_p thread;
frame_p frame, new_frame;
parse_state* state;
- char full_doc[1024], *name;
+ char full_doc[1024], *name, *frame_name;
code_p code;
int i;
@@ -1819,7 +1829,11 @@
set_obj_doc(module, full_doc);
frame = ist->frame;
//new_locals = NEW_OBJ(NULL);
- new_frame = create_frame( ist, NULL, NULL, NULL, module, NULL, code );
+ if (filename)
+ frame_name = filename;
+ else
+ frame_name = "execString";
+ new_frame = create_frame( ist, NULL, NULL, NULL, module, NULL, code, frame_name );
new_frame->called_from_c = TRUE;
if (frame) ist->frame->next_frame = new_frame;
new_frame->prev_frame = ist->frame;
@@ -1934,7 +1948,7 @@
}
new_locals = NEW_OBJ(NULL);
thread_module = NEW_OBJ(NULL);
- new_frame = create_frame( ist, thread_module, thread_module, NULL, new_locals, func_obj, NULL );
+ new_frame = create_frame(ist, thread_module, thread_module, NULL, new_locals, func_obj, NULL , NULL);
new_frame->called_from_c = TRUE;
new_frame->prev_frame = NULL;
load_frame_params( ist, new_locals, func_obj, parm_cnt, lbl_val_arr);
@@ -1992,10 +2006,8 @@
pr_assert(param);
fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_NOP", param, codedata(str, code, op, param, pc));
break;
- case OP_SAVE_TMP: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_SAVE_TMP", param, codedata(str, code, op, param, pc));
+ case OP_CLRSP: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_CLRSP", param, codedata(str, code, op, param, pc));
break;
- case OP_RESTORE_TMP: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_RESTORE_TMP", param, codedata(str, code, op, param, pc));
- break;
case OP_IMPORT: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_IMPORT", param, codedata(str, code, op, param, pc));
break;
case OP_IMPORT_AS: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_IMPORT_AS", param, codedata(str, code, op, param, pc));
Modified: trunk/src/interp.h
===================================================================
--- trunk/src/interp.h 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/interp.h 2004-06-03 21:30:56 UTC (rev 567)
@@ -91,6 +91,7 @@
code_p code;
clist_p exc_stack;
int stack_ptr;
+ char* func_name;
obj_p stack[];
} frame_t;
@@ -113,7 +114,7 @@
} fparam_proc_state_t;
frame_p create_frame( isp ist, obj_p self, obj_p syn_locals, obj_p dyn_locals,
- obj_p locals, obj_p func_obj, code_p code_in );
+ obj_p locals, obj_p func_obj, code_p code_in, char* name );
void *main_thread(apr_thread_t *handle, void *filename);
void *user_thread(apr_thread_t *handle, void *argv);
Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/object.c 2004-06-03 21:30:56 UTC (rev 567)
@@ -992,6 +992,7 @@
if (scope == super_obj) super_obj = NULL;
last_scope = scope;
scope = get_attr(ist, scope, SYM(PREVSCOPE_));
+ pr_assert(last_scope != scope);
}
if (!res && last_scope)
return get_proto_attr(ist, last_scope, key, scope_pp, super_obj);
Modified: trunk/src/parser_routines.c
===================================================================
--- trunk/src/parser_routines.c 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/parser_routines.c 2004-06-03 21:30:56 UTC (rev 567)
@@ -1167,21 +1167,20 @@
int len=0, stack_depth=0, max_stack_depth = 0;
int k=0, end_icall_loc, end_exc_loc, end_loc;
calc_code(rparm, &len, &stack_depth, &max_stack_depth);
- len += 2;
+ len += 1;
calc_code(ref, &len, &stack_depth, &max_stack_depth);
len += 9;
end_icall_loc = len;
len += 4;
calc_code(ref, &len, &stack_depth, &max_stack_depth);
- len += 6;
+ len += 7;
calc_code(ref, &len, &stack_depth, &max_stack_depth);
- len += 3;
+ len += 2;
end_exc_loc = len;
len++;
end_loc = len;
res = new_code(param, len, stack_depth, max_stack_depth, 0);
add_code(rparm, res, &k);
- res->code_data[k++].bytecode.opcode = OP_SAVE_TMP;
res->code_data[k ].bytecode.opcode = OP_TRYEXCEPT;
res->code_data[k ].bytecode.param = end_icall_loc - k;
k++;
@@ -1192,11 +1191,12 @@
res->code_data[k++].data = sym_id_table[iop].id;
res->code_data[k++].data = NULL;
res->code_data[k++].data = PARAM_NORMAL;
- res->code_data[k++].bytecode.opcode = OP_RESTORE_TMP;
+ res->code_data[k ].bytecode.opcode = OP_DUPLICATE;
+ res->code_data[k++].bytecode.param = -5;
res->code_data[k ].bytecode.opcode = OP_CALL;
res->code_data[k++].bytecode.param = 1;
res->code_data[k ].bytecode.opcode = OP_POP;
- res->code_data[k++].bytecode.param = 1;
+ res->code_data[k++].bytecode.param = 2;
res->code_data[k ].bytecode.opcode = OP_BR;
res->code_data[k ].bytecode.param = end_loc - k;
k++;
@@ -1215,18 +1215,19 @@
res->code_data[k++].data = sym_id_table[op].id;
res->code_data[k++].data = NULL;
res->code_data[k++].data = PARAM_NORMAL;
- res->code_data[k++].bytecode.opcode = OP_RESTORE_TMP;
+ res->code_data[k ].bytecode.opcode = OP_DUPLICATE;
+ res->code_data[k++].bytecode.param = -5;
res->code_data[k ].bytecode.opcode = OP_CALL;
res->code_data[k++].bytecode.param = 1;
add_code(ref, res, &k);
res->code_data[k ].bytecode.opcode = OP_ASSIGN;
res->code_data[k++].bytecode.param = 1;
res->code_data[k ].bytecode.opcode = OP_POP;
- res->code_data[k++].bytecode.param = 1;
+ res->code_data[k++].bytecode.param = 2;
pr_assert(end_exc_loc = k);
res->code_data[k++].bytecode.opcode = OP_RERAISE;
pr_assert(end_loc = k);
- res->stack_depth -= 7;
+ res->stack_depth = 0;
return debug_retrn(__LINE__, res);
}
code_p while_expr_body_else(void* param, obj_p label, code_p expr, code_p body, code_p els){
@@ -1598,6 +1599,7 @@
calc_code(body, &len, &stack_depth, &max_stack_depth);
len += 2;
except_loc = len;
+ len += 1;
for(i=0; i < llen; i++)
calc_code(clist_item(except_list,i), &len, &stack_depth, &max_stack_depth);
len += llen + 1;
@@ -1614,6 +1616,7 @@
res->code_data[k ].bytecode.param = els_loc - k;
k++;
pr_assert(except_loc == k);
+ res->code_data[k++].bytecode.opcode = OP_CLRSP;
for (i = 0; i < llen; i++, k++) {
add_code(clist_item(except_list,i), res, &k);
res->code_data[k ].bytecode.opcode = OP_BR;
@@ -1628,12 +1631,13 @@
}
code_p tryfinally_body(void* param, code_p body, code_p final){
code *res;
- int k=0, len=2, stack_depth=0, max_stack_depth = 0;
+ int k=0, len=3, stack_depth=0, max_stack_depth = 0;
calc_code(body, &len, &stack_depth, &max_stack_depth);
calc_code(final, &len, &stack_depth, &max_stack_depth);
res = new_code(param, len, stack_depth, max_stack_depth, OP_TRYFINALLY);
res->code_data[k++].bytecode.param = body->len+1;
add_code(body, res, &k);
+ res->code_data[k++].bytecode.opcode = OP_CLRSP;
add_code(final, res, &k);
res->code_data[k++].bytecode.opcode = OP_RERAISE;
pr_assert(res->len == k);
Modified: trunk/src/prothon.y
===================================================================
--- trunk/src/prothon.y 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/prothon.y 2004-06-03 21:30:56 UTC (rev 567)
@@ -992,6 +992,11 @@
str_ptr[str_index++]=0;
str_ptr = pr_realloc(str_ptr, str_index);
lvalp->str_type = new_string_n_obj((((parse_state*) yylex_param)->ist), str_ptr, str_index-1);
+#ifdef TRACE_PARSER
+ if (trace_parser){
+ fprintf((((parse_state*) yylex_param)->debug_stream, "\"%s\"\n",str_ptr);
+ }
+#endif
return STRING;
}
goto not_quote;
@@ -1153,6 +1158,11 @@
str_ptr = pr_realloc(str_ptr, str_index);
lvalp->str_type = new_string_n_obj((((parse_state*) yylex_param)->ist), str_ptr, str_index-1);
+#ifdef TRACE_PARSER
+ if (trace_parser){
+ fprintf((((parse_state*) yylex_param)->debug_stream, "\"%s\"\n",str_ptr);
+ }
+#endif
return LABEL;
}
/* process dot, int, or float */
Modified: trunk/src/sys.c
===================================================================
--- trunk/src/sys.c 2004-06-03 08:51:39 UTC (rev 566)
+++ trunk/src/sys.c 2004-06-03 21:30:56 UTC (rev 567)
@@ -174,7 +174,7 @@
path[len-1] = 0;
strcpy(home, path);
have_home = TRUE;
- set_attr(ist, sys_module, sym(ist, "prothonhome"), NEW_STRING(home));
+ set_attr(ist, sys_module, sym(ist, "home"), NEW_STRING(home));
}
}
if (!have_home) {
@@ -193,7 +193,6 @@
list_append(ist, vers_tuple, NEW_STRING(PROTHON_VERSION_DATE));
vers_tuple->immutable = TRUE;
set_attr(ist, sys_module, sym(ist, "version"), vers_tuple);
- set_attr(ist, sys_module, sym(ist, "maxint"), NEW_INT(MAX_INT_VAL));
set_attr(ist, sys_module, sym(ist, "modules"), OBJ(MODULES));
set_attr( ist, sys_module, sym(ist, "exit"),
new_C_func_obj(ist, sys_exit, list2(ist, sym(ist,"num"),NEW_INT(1))) );