From 1d73ecb7929e66c6025e56308acca2923dbed1cf Mon Sep 17 00:00:00 2001 From: Konrad Hinsen Date: Wed, 10 Apr 2013 14:26:16 +0200 Subject: [PATCH 1/3] Handle float and complex constants in addition to integer --- hy/compiler.py | 18 ++++++++++++++++-- hy/lex/states.py | 15 +++++++++++++++ hy/models/complex.py | 32 ++++++++++++++++++++++++++++++++ hy/models/float.py | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 hy/models/complex.py create mode 100644 hy/models/float.py diff --git a/hy/compiler.py b/hy/compiler.py index d1d4772..6dc1842 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -25,6 +25,8 @@ from hy.errors import HyError from hy.models.expression import HyExpression from hy.models.integer import HyInteger +from hy.models.float import HyFloat +from hy.models.complex import HyComplex from hy.models.string import HyString from hy.models.symbol import HySymbol from hy.models.list import HyList @@ -894,8 +896,20 @@ class HyASTCompiler(object): return ret @builds(HyInteger) - def compile_number(self, number): - return ast.Num(n=int(number), # See HyInteger above. + def compile_integer(self, number): + return ast.Num(n=int(number), + lineno=number.start_line, + col_offset=number.start_column) + + @builds(HyFloat) + def compile_integer(self, number): + return ast.Num(n=float(number), + lineno=number.start_line, + col_offset=number.start_column) + + @builds(HyComplex) + def compile_integer(self, number): + return ast.Num(n=complex(number), lineno=number.start_line, col_offset=number.start_column) diff --git a/hy/lex/states.py b/hy/lex/states.py index 52d6fa3..da0f466 100644 --- a/hy/lex/states.py +++ b/hy/lex/states.py @@ -20,6 +20,8 @@ from hy.models.expression import HyExpression from hy.models.integer import HyInteger +from hy.models.float import HyFloat +from hy.models.complex import HyComplex from hy.models.symbol import HySymbol from hy.models.string import HyString from hy.models.dict import HyDict @@ -45,6 +47,8 @@ def _resolve_atom(obj): Resolve a bare atom into one of the following (in order): - Integer + - Float + - Complex - Symbol """ try: @@ -52,6 +56,17 @@ def _resolve_atom(obj): except ValueError: pass + try: + return HyFloat(obj) + except ValueError: + pass + + try: + return HyComplex(obj) + except ValueError: + pass + + table = { "true": "True", "false": "False", diff --git a/hy/models/complex.py b/hy/models/complex.py new file mode 100644 index 0000000..9647997 --- /dev/null +++ b/hy/models/complex.py @@ -0,0 +1,32 @@ +# Copyright (c) 2013 Paul Tagliamonte +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +from hy.models import HyObject + + +class HyComplex(HyObject, complex): + """ + Internal represntation of a Hy Complex. May raise a ValueError as if + complex(foo) was called, given HyComplex(foo). + """ + + def __new__(cls, number, *args, **kwargs): + number = complex(number) + return super(HyComplex, cls).__new__(cls, number) diff --git a/hy/models/float.py b/hy/models/float.py new file mode 100644 index 0000000..184c3a3 --- /dev/null +++ b/hy/models/float.py @@ -0,0 +1,32 @@ +# Copyright (c) 2013 Paul Tagliamonte +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +from hy.models import HyObject + + +class HyFloat(HyObject, float): + """ + Internal represntation of a Hy Float. May raise a ValueError as if + float(foo) was called, given HyFloat(foo). + """ + + def __new__(cls, number, *args, **kwargs): + number = float(number) + return super(HyFloat, cls).__new__(cls, number) From ac0a597742d30e32315aade49003690062724272 Mon Sep 17 00:00:00 2001 From: Konrad Hinsen Date: Thu, 11 Apr 2013 09:54:59 +0200 Subject: [PATCH 2/3] Tests for float and complex constants --- tests/lex/test_lex.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/lex/test_lex.py b/tests/lex/test_lex.py index 45922b9..676c109 100644 --- a/tests/lex/test_lex.py +++ b/tests/lex/test_lex.py @@ -20,6 +20,8 @@ from hy.models.expression import HyExpression from hy.models.integer import HyInteger +from hy.models.float import HyFloat +from hy.models.complex import HyComplex from hy.models.symbol import HySymbol from hy.models.string import HyString from hy.models.dict import HyDict @@ -77,6 +79,25 @@ def test_lex_expression_integer(): assert objs == [HyExpression([HySymbol("foo"), HyInteger(2)])] +def test_lex_expression_float(): + """ Make sure expressions can produce floats """ + objs = tokenize("(foo 2.)") + assert objs == [HyExpression([HySymbol("foo"), HyFloat(2.)])] + objs = tokenize("(foo -0.5)") + assert objs == [HyExpression([HySymbol("foo"), HyFloat(-0.5)])] + objs = tokenize("(foo 1.e7)") + assert objs == [HyExpression([HySymbol("foo"), HyFloat(1.e7)])] + +def test_lex_expression_complex(): + """ Make sure expressions can produce complex """ + objs = tokenize("(foo 2.j)") + assert objs == [HyExpression([HySymbol("foo"), HyComplex(2.j)])] + objs = tokenize("(foo -0.5j)") + assert objs == [HyExpression([HySymbol("foo"), HyComplex(-0.5j)])] + objs = tokenize("(foo 1.e7j)") + assert objs == [HyExpression([HySymbol("foo"), HyComplex(1.e7j)])] + + def test_lex_line_counting(): """ Make sure we can count lines / columns """ entry = tokenize("(foo (one two))")[0] From 15ae8c83f16866ac3b15e805e5c583047622eab9 Mon Sep 17 00:00:00 2001 From: Konrad Hinsen Date: Thu, 11 Apr 2013 14:41:09 +0200 Subject: [PATCH 3/3] Fix names of methods compile_float and compile_complex --- hy/compiler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hy/compiler.py b/hy/compiler.py index 6dc1842..57c55ad 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -902,13 +902,13 @@ class HyASTCompiler(object): col_offset=number.start_column) @builds(HyFloat) - def compile_integer(self, number): + def compile_float(self, number): return ast.Num(n=float(number), lineno=number.start_line, col_offset=number.start_column) @builds(HyComplex) - def compile_integer(self, number): + def compile_complex(self, number): return ast.Num(n=complex(number), lineno=number.start_line, col_offset=number.start_column)