Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
1aa2c102
Commit
1aa2c102
authored
Mar 31, 2014
by
Damien George
Browse files
Merge branch 'master' of github.com:micropython/micropython
parents
523b5750
6ded55a6
Changes
8
Hide whitespace changes
Inline
Side-by-side
py/compile.c
View file @
1aa2c102
...
...
@@ -145,7 +145,9 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
}
else
if
(
MP_PARSE_NODE_IS_TOKEN_KIND
(
pns
->
nodes
[
1
],
MP_TOKEN_OP_PERCENT
))
{
pn
=
mp_parse_node_new_leaf
(
MP_PARSE_NODE_SMALL_INT
,
python_modulo
(
arg0
,
arg1
));
}
else
if
(
MP_PARSE_NODE_IS_TOKEN_KIND
(
pns
->
nodes
[
1
],
MP_TOKEN_OP_DBL_SLASH
))
{
pn
=
mp_parse_node_new_leaf
(
MP_PARSE_NODE_SMALL_INT
,
python_floor_divide
(
arg0
,
arg1
));
if
(
arg1
!=
0
)
{
pn
=
mp_parse_node_new_leaf
(
MP_PARSE_NODE_SMALL_INT
,
python_floor_divide
(
arg0
,
arg1
));
}
}
else
{
// shouldn't happen
assert
(
0
);
...
...
py/obj.c
View file @
1aa2c102
...
...
@@ -62,7 +62,7 @@ void mp_obj_print_exception(mp_obj_t exc) {
}
}
}
mp_obj_print
(
exc
,
PRINT_
REPR
);
mp_obj_print
(
exc
,
PRINT_
EXC
);
printf
(
"
\n
"
);
}
...
...
py/obj.h
View file @
1aa2c102
...
...
@@ -141,7 +141,9 @@ typedef mp_obj_t (*mp_fun_var_t)(uint n, const mp_obj_t *);
typedef
mp_obj_t
(
*
mp_fun_kw_t
)(
uint
n
,
const
mp_obj_t
*
,
mp_map_t
*
);
typedef
enum
{
PRINT_STR
,
PRINT_REPR
PRINT_STR
,
PRINT_REPR
,
PRINT_EXC
,
// Special format for printing exception in unhandled exception message
}
mp_print_kind_t
;
typedef
void
(
*
mp_print_fun_t
)(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
o
,
mp_print_kind_t
kind
);
...
...
py/objexcept.c
View file @
1aa2c102
...
...
@@ -11,42 +11,34 @@
#include
"runtime.h"
#include
"runtime0.h"
// This is unified class for C-level and Python-level exceptions
// Python-level exceptions have empty ->msg and all arguments are in
// args tuple. C-level exceptions likely have ->msg set, and args is empty.
typedef
struct
_mp_obj_exception_t
{
mp_obj_base_t
base
;
mp_obj_t
traceback
;
// a list object, holding (file,line,block) as numbers (not Python objects); a hack for now
vstr_t
*
msg
;
mp_obj_tuple_t
args
;
}
mp_obj_exception_t
;
// Instance of GeneratorExit exception - needed by generator.close()
// This would belong to objgenerator.c, but to keep mp_obj_exception_t
// definition module-private so far, have it here.
const
mp_obj_exception_t
mp_const_GeneratorExit_obj
=
{{
&
mp_type_GeneratorExit
},
MP_OBJ_NULL
,
NULL
,
{{
&
mp_type_tuple
},
0
}};
const
mp_obj_exception_t
mp_const_GeneratorExit_obj
=
{{
&
mp_type_GeneratorExit
},
MP_OBJ_NULL
,
{{
&
mp_type_tuple
},
0
}};
STATIC
void
mp_obj_exception_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
o_in
,
mp_print_kind_t
kind
)
{
mp_obj_exception_t
*
o
=
o_in
;
if
(
o
->
msg
!=
NULL
)
{
print
(
env
,
"%s: %s"
,
qstr_str
(
o
->
base
.
type
->
name
),
vstr_str
(
o
->
msg
));
}
else
{
// Yes, that's how CPython has it
// TODO now that exceptions are classes and instances, I think this needs to be changed to match CPython
if
(
kind
==
PRINT_REPR
)
{
print
(
env
,
"%s"
,
qstr_str
(
o
->
base
.
type
->
name
));
}
if
(
kind
==
PRINT_STR
)
{
if
(
o
->
args
.
len
==
0
)
{
print
(
env
,
""
);
return
;
}
else
if
(
o
->
args
.
len
==
1
)
{
mp_obj_print_helper
(
print
,
env
,
o
->
args
.
items
[
0
],
PRINT_STR
);
return
;
}
if
(
kind
==
PRINT_REPR
)
{
print
(
env
,
"%s"
,
qstr_str
(
o
->
base
.
type
->
name
));
}
else
if
(
kind
==
PRINT_EXC
)
{
print
(
env
,
"%s: "
,
qstr_str
(
o
->
base
.
type
->
name
));
}
if
(
kind
==
PRINT_STR
||
kind
==
PRINT_EXC
)
{
if
(
o
->
args
.
len
==
0
)
{
print
(
env
,
""
);
return
;
}
else
if
(
o
->
args
.
len
==
1
)
{
mp_obj_print_helper
(
print
,
env
,
o
->
args
.
items
[
0
],
PRINT_STR
);
return
;
}
tuple_print
(
print
,
env
,
&
o
->
args
,
kind
);
}
tuple_print
(
print
,
env
,
&
o
->
args
,
kind
);
}
STATIC
mp_obj_t
mp_obj_exception_make_new
(
mp_obj_t
type_in
,
uint
n_args
,
uint
n_kw
,
const
mp_obj_t
*
args
)
{
...
...
@@ -59,7 +51,6 @@ STATIC mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
mp_obj_t
,
n_args
);
o
->
base
.
type
=
type
;
o
->
traceback
=
MP_OBJ_NULL
;
o
->
msg
=
NULL
;
o
->
args
.
base
.
type
=
&
mp_type_tuple
;
o
->
args
.
len
=
n_args
;
memcpy
(
o
->
args
.
items
,
args
,
n_args
*
sizeof
(
mp_obj_t
));
...
...
@@ -185,7 +176,7 @@ MP_DEFINE_EXCEPTION(Exception, BaseException)
*/
mp_obj_t
mp_obj_new_exception
(
const
mp_obj_type_t
*
exc_type
)
{
return
mp_obj_new_exception_
msg_v
arg
(
exc_type
,
NULL
);
return
mp_obj_new_exception_arg
s
(
exc_type
,
0
,
NULL
);
}
mp_obj_t
mp_obj_new_exception_args
(
const
mp_obj_type_t
*
exc_type
,
uint
n_args
,
const
mp_obj_t
*
args
)
{
...
...
@@ -202,22 +193,25 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char
assert
(
exc_type
->
make_new
==
mp_obj_exception_make_new
);
// make exception object
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
mp_obj_t
,
0
);
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
mp_obj_t
,
1
);
o
->
base
.
type
=
exc_type
;
o
->
traceback
=
MP_OBJ_NULL
;
o
->
args
.
base
.
type
=
&
mp_type_tuple
;
o
->
args
.
len
=
0
;
o
->
args
.
len
=
1
;
if
(
fmt
==
NULL
)
{
// no message
o
->
msg
=
NULL
;
assert
(
0
)
;
}
else
{
// render exception message
o
->
msg
=
vstr_new
();
// render exception message and store as .args[0]
// TODO: optimize bufferbloat
vstr_t
*
vstr
=
vstr_new
();
va_list
ap
;
va_start
(
ap
,
fmt
);
vstr_vprintf
(
o
->
msg
,
fmt
,
ap
);
vstr_vprintf
(
vstr
,
fmt
,
ap
);
va_end
(
ap
);
o
->
args
.
items
[
0
]
=
mp_obj_new_str
((
byte
*
)
vstr
->
buf
,
vstr
->
len
,
false
);
vstr_free
(
vstr
);
}
return
o
;
...
...
py/objfloat.c
View file @
1aa2c102
#include
<stdlib.h>
#include
<stdio.h>
#include
<string.h>
#include
<assert.h>
#include
<math.h>
...
...
@@ -23,7 +25,13 @@ STATIC void float_print(void (*print)(void *env, const char *fmt, ...), void *en
format_float
(
o
->
value
,
buf
,
sizeof
(
buf
),
'g'
,
6
,
'\0'
);
print
(
env
,
"%s"
,
buf
);
#else
print
(
env
,
"%.8g"
,
(
double
)
o
->
value
);
char
buf
[
32
];
sprintf
(
buf
,
"%.8g"
,
(
double
)
o
->
value
);
print
(
env
,
buf
);
if
(
strchr
(
buf
,
'.'
)
==
NULL
)
{
// Python floats always have decimal point
print
(
env
,
".0"
);
}
#endif
}
...
...
@@ -103,13 +111,15 @@ mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs_in) {
case
MP_BINARY_OP_INPLACE_SUBTRACT
:
lhs_val
-=
rhs_val
;
break
;
case
MP_BINARY_OP_MULTIPLY
:
case
MP_BINARY_OP_INPLACE_MULTIPLY
:
lhs_val
*=
rhs_val
;
break
;
/
*
TODO
floor(?) the value
/
/
TODO
: verify that C floor matches Python semantics
case
MP_BINARY_OP_FLOOR_DIVIDE
:
case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break;
*/
case
MP_BINARY_OP_INPLACE_FLOOR_DIVIDE
:
lhs_val
=
MICROPY_FLOAT_C_FUN
(
floor
)(
lhs_val
/
rhs_val
);
goto
check_zero_division
;
case
MP_BINARY_OP_TRUE_DIVIDE
:
case
MP_BINARY_OP_INPLACE_TRUE_DIVIDE
:
lhs_val
/=
rhs_val
;
check_zero_division:
if
(
isinf
(
lhs_val
)){
// check for division by zero
nlr_jump
(
mp_obj_new_exception_msg
(
&
mp_type_ZeroDivisionError
,
"float division by zero"
));
}
...
...
@@ -119,7 +129,8 @@ mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs_in) {
case
MP_BINARY_OP_LESS_EQUAL
:
return
MP_BOOL
(
lhs_val
<=
rhs_val
);
case
MP_BINARY_OP_MORE_EQUAL
:
return
MP_BOOL
(
lhs_val
>=
rhs_val
);
return
NULL
;
// op not supported
default:
return
NULL
;
// op not supported
}
return
mp_obj_new_float
(
lhs_val
);
}
...
...
py/runtime.c
View file @
1aa2c102
...
...
@@ -348,13 +348,20 @@ mp_obj_t mp_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
}
case
MP_BINARY_OP_FLOOR_DIVIDE
:
case
MP_BINARY_OP_INPLACE_FLOOR_DIVIDE
:
{
if
(
rhs_val
==
0
)
{
goto
zero_division
;
}
lhs_val
=
python_floor_divide
(
lhs_val
,
rhs_val
);
break
;
}
#if MICROPY_ENABLE_FLOAT
case
MP_BINARY_OP_TRUE_DIVIDE
:
case
MP_BINARY_OP_INPLACE_TRUE_DIVIDE
:
return
mp_obj_new_float
((
mp_float_t
)
lhs_val
/
(
mp_float_t
)
rhs_val
);
case
MP_BINARY_OP_INPLACE_TRUE_DIVIDE
:
if
(
rhs_val
==
0
)
{
zero_division:
nlr_jump
(
mp_obj_new_exception_msg
(
&
mp_type_ZeroDivisionError
,
"division by zero"
));
}
return
mp_obj_new_float
((
mp_float_t
)
lhs_val
/
(
mp_float_t
)
rhs_val
);
#endif
case
MP_BINARY_OP_MODULO
:
...
...
tests/basics/float1.py
View file @
1aa2c102
# basic float
x
=
1
/
2
print
(
x
)
print
(
1.0
//
2
)
print
(
2.0
//
2
)
try
:
1.0
/
0
except
ZeroDivisionError
:
print
(
"ZeroDivisionError"
)
try
:
1.0
//
0
except
ZeroDivisionError
:
print
(
"ZeroDivisionError"
)
tests/basics/int-divzero.py
0 → 100644
View file @
1aa2c102
try
:
1
/
0
except
ZeroDivisionError
:
print
(
"ZeroDivisionError"
)
try
:
1
//
0
except
ZeroDivisionError
:
print
(
"ZeroDivisionError"
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment