Commit 2f022483 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Changed compiler directive comment format

--HG--
rename : tests/compile/c_options.pyx => tests/compile/c_directives.pyx
rename : tests/errors/e_options.pyx => tests/errors/e_directives.pyx
parent 8fc68f38
...@@ -79,9 +79,7 @@ def make_lexicon(): ...@@ -79,9 +79,7 @@ def make_lexicon():
escaped_newline = Str("\\\n") escaped_newline = Str("\\\n")
lineterm = Eol + Opt(Str("\n")) lineterm = Eol + Opt(Str("\n"))
comment_start = Str("#") comment = Str("#") + Rep(AnyBut("\n"))
comment = comment_start + Rep(AnyBut("\n"))
option_comment = comment_start + Str("cython:") + Rep(AnyBut("\n"))
return Lexicon([ return Lexicon([
(name, 'IDENT'), (name, 'IDENT'),
...@@ -98,13 +96,12 @@ def make_lexicon(): ...@@ -98,13 +96,12 @@ def make_lexicon():
#(stringlit, 'STRING'), #(stringlit, 'STRING'),
(beginstring, Method('begin_string_action')), (beginstring, Method('begin_string_action')),
(option_comment, Method('option_comment')),
(comment, IGNORE), (comment, IGNORE),
(spaces, IGNORE), (spaces, IGNORE),
(escaped_newline, IGNORE), (escaped_newline, IGNORE),
State('INDENT', [ State('INDENT', [
(option_comment + lineterm, Method('option_comment')), (comment + lineterm, Method('commentline')),
(Opt(spaces) + Opt(comment) + lineterm, IGNORE), (Opt(spaces) + Opt(comment) + lineterm, IGNORE),
(indentation, Method('indentation_action')), (indentation, Method('indentation_action')),
(Eof, Method('eof_action')) (Eof, Method('eof_action'))
......
...@@ -63,6 +63,30 @@ option_defaults = { ...@@ -63,6 +63,30 @@ option_defaults = {
'boundscheck' : True 'boundscheck' : True
} }
def parse_option_value(name, value):
"""
Parses value as an option value for the given name and returns
the interpreted value. None is returned if the option does not exist.
>>> print parse_option_value('nonexisting', 'asdf asdfd')
None
>>> parse_option_value('boundscheck', 'True')
True
>>> parse_option_value('boundscheck', 'true')
Traceback (most recent call last):
...
ValueError: boundscheck directive must be set to True or False
"""
type = option_types.get(name)
if not type: return None
if type is bool:
if value == "True": return True
elif value == "False": return False
else: raise ValueError("%s directive must be set to True or False" % name)
else:
assert False
def parse_option_list(s): def parse_option_list(s):
""" """
Parses a comma-seperated list of pragma options. Whitespace Parses a comma-seperated list of pragma options. Whitespace
......
...@@ -2348,14 +2348,20 @@ def p_code(s, level=None): ...@@ -2348,14 +2348,20 @@ def p_code(s, level=None):
repr(s.sy), repr(s.systring))) repr(s.sy), repr(s.systring)))
return body return body
def p_option_comments(s): COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*([a-z]+)\s*=(.*)$")
def p_compiler_directive_comments(s):
result = {} result = {}
while s.sy == 'option_comment': while s.sy == 'commentline':
opts = s.systring[len("#cython:"):] m = COMPILER_DIRECTIVE_COMMENT_RE.match(s.systring)
if m:
name = m.group(1)
try: try:
result.update(Options.parse_option_list(opts)) value = Options.parse_option_value(str(name), str(m.group(2).strip()))
except ValueError, e: except ValueError, e:
s.error(e.message, fatal=False) s.error(e.message, fatal=False)
if value is not None: # can be False!
result[name] = value
s.next() s.next()
return result return result
...@@ -2369,8 +2375,8 @@ def p_module(s, pxd, full_module_name): ...@@ -2369,8 +2375,8 @@ def p_module(s, pxd, full_module_name):
else: else:
level = 'module' level = 'module'
option_comments = p_option_comments(s) option_comments = p_compiler_directive_comments(s)
s.parse_option_comments = False s.parse_comments = False
body = p_statement_list(s, Ctx(level = level), first_statement = 1) body = p_statement_list(s, Ctx(level = level), first_statement = 1)
if s.sy != 'EOF': if s.sy != 'EOF':
s.error("Syntax error in statement [%s,%s]" % ( s.error("Syntax error in statement [%s,%s]" % (
......
...@@ -306,7 +306,7 @@ class PyrexScanner(Scanner): ...@@ -306,7 +306,7 @@ class PyrexScanner(Scanner):
self.compile_time_env = initial_compile_time_env() self.compile_time_env = initial_compile_time_env()
self.compile_time_eval = 1 self.compile_time_eval = 1
self.compile_time_expr = 0 self.compile_time_expr = 0
self.parse_option_comments = True self.parse_comments = True
self.source_encoding = source_encoding self.source_encoding = source_encoding
self.trace = trace_scanner self.trace = trace_scanner
self.indentation_stack = [0] self.indentation_stack = [0]
...@@ -316,12 +316,9 @@ class PyrexScanner(Scanner): ...@@ -316,12 +316,9 @@ class PyrexScanner(Scanner):
self.sy = '' self.sy = ''
self.next() self.next()
def option_comment(self, text): def commentline(self, text):
# #cython:-comments should be treated as literals until if self.parse_comments:
# parse_option_comments is set to False, at which point self.produce('commentline', text)
# they should be ignored.
if self.parse_option_comments:
self.produce('option_comment', text)
def current_level(self): def current_level(self):
return self.indentation_stack[-1] return self.indentation_stack[-1]
......
#cython: boundscheck=False # boundscheck = False
# ignoreme = OK
# This testcase is most useful if you inspect the generated C file
print 3 print 3
cimport python_dict as asadf, python_exc, cython as cy cimport python_dict as asadf, python_exc, cython as cy
def e(object[int, 2] buf):
print buf[3, 2] # no bc
@cy.boundscheck(False) @cy.boundscheck(False)
def f(object[int, 2] buf): def f(object[int, 2] buf):
print buf[3, 2] print buf[3, 2] # no bc
@cy.boundscheck(True) @cy.boundscheck(True)
def g(object[int, 2] buf): def g(object[int, 2] buf):
# Please leave this comment, # The below line should have no meaning
#cython: this should have no special meaning # boundscheck = False
# even if the above line doesn't follow indentation. # even if the above line doesn't follow indentation.
print buf[3, 2] print buf[3, 2] # bc
def h(object[int, 2] buf): def h(object[int, 2] buf):
print buf[3, 2] print buf[3, 2] # no bc
with cy.boundscheck(True): with cy.boundscheck(True):
print buf[3,2] print buf[3,2] # bc
from cython cimport boundscheck as bc from cython cimport boundscheck as bc
def i(object[int] buf): def i(object[int] buf):
with bc(True): with bc(True):
print buf[3] print buf[3] # bs
# nonexistant = True
# boundscheck = true
# boundscheck = 9
print 3
# Options should not be interpreted any longer:
# boundscheck = true
_ERRORS = u"""
3:0: boundscheck directive must be set to True or False
4:0: boundscheck directive must be set to True or False
"""
#cython: nonexistant
#cython: some=9
# The one below should NOT raise an error
#cython: boundscheck=True
# However this one should
#cython: boundscheck=sadf
print 3
#cython: boundscheck=True
_ERRORS = u"""
2:0: Expected "=" in option "nonexistant"
3:0: Unknown option: "some"
10:0: Must pass a boolean value for option "boundscheck"
"""
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment