Skip to content
Snippets Groups Projects
Commit c178ea47 authored by xyb's avatar xyb
Browse files

Implemented int(str) in UNIX

parent 729e9cce
No related branches found
No related tags found
No related merge requests found
......@@ -13,6 +13,7 @@
#include "runtime0.h"
#include "runtime.h"
#include "map.h"
#include "strtonum.h"
mp_obj_t mp_obj_get_type(mp_obj_t o_in) {
if (MP_OBJ_IS_SMALL_INT(o_in)) {
......@@ -136,6 +137,12 @@ bool mp_obj_less(mp_obj_t o1, mp_obj_t o2) {
}
machine_int_t mp_obj_get_int(mp_obj_t arg) {
return mp_obj_get_int_base(arg, 0);
}
machine_int_t mp_obj_get_int_base(mp_obj_t arg, mp_obj_t base_arg) {
const char *value;
int base;
if (arg == mp_const_false) {
return 0;
} else if (arg == mp_const_true) {
......@@ -147,6 +154,17 @@ machine_int_t mp_obj_get_int(mp_obj_t arg) {
// TODO work out if this should be floor, ceil or trunc
return (machine_int_t)mp_obj_float_get(arg);
#endif
} else if (MP_OBJ_IS_TYPE(arg, &str_type)) {
if (base_arg == 0) {
value = qstr_str(mp_obj_str_get(arg));
return (machine_int_t)strtonum(value, 0);
} else if (MP_OBJ_IS_TYPE(base_arg, &int_type)) {
base = MP_OBJ_SMALL_INT_VALUE(base_arg);
value = qstr_str(mp_obj_str_get(arg));
return (machine_int_t)strtonum(value, base);
} else {
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "an integer is required"));
}
} else {
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg)));
}
......
......@@ -235,6 +235,7 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2);
bool mp_obj_less(mp_obj_t o1, mp_obj_t o2);
machine_int_t mp_obj_get_int(mp_obj_t arg);
machine_int_t mp_obj_get_int_base(mp_obj_t arg, mp_obj_t base_arg);
#if MICROPY_ENABLE_FLOAT
mp_float_t mp_obj_get_float(mp_obj_t self_in);
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
......
......@@ -22,8 +22,9 @@ static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args)
// TODO allow string as arg and parse it
return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
//case 2:
// TODO, parse with given base
case 2:
// TODO make args[0] and args[1] correct
return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int_base(args[0], args[1]));
default:
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args));
......
......@@ -70,6 +70,7 @@ PY_O_BASENAME = \
emitinlinethumb.o \
runtime.o \
map.o \
strtonum.o \
obj.o \
objbool.o \
objboundmeth.o \
......
#if defined(UNIX)
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "misc.h"
#include "mpconfig.h"
#include "mpqstr.h"
#include "nlr.h"
#include "obj.h"
long strtonum(const char *restrict s, int base) {
int c, neg = 0;
const char *p = s;
char *num;
long found;
// check radix base
if ((base != 0 && base < 2) || base > 36) {
printf("ValueError: int() arg 2 must be >=2 and <= 36\n");
return 0;
}
// skip surrounded whitespace
while (isspace((c = *(p++))));
if (c == 0) {
goto value_error;
}
// preced sign
if (c == '+' || c == '-') {
neg = - (c == '-');
c = *(p++);
}
// find real radix base, and strip preced '0x', '0o' and '0b'
if ((base == 0 || base == 16) && c == '0') {
c = *(p++);
if ((c | 32) == 'x') {
base = 16;
} else if (base == 0 && (c | 32) == 'o') {
base = 8;
} else if (base == 0 && (c | 32) == 'b') {
base = 2;
} else {
base = 10;
p -= 2;
}
} else if (base == 8 && c == '0') {
if ((c | 32) == 'o') {
base = 8;
} else {
goto value_error;
}
} else if (base == 2 && c == '0') {
if ((c | 32) == 'b') {
base = 2;
} else {
goto value_error;
}
} else {
if (base == 0) base = 10;
p--;
}
found = strtol(p, &num, base);
if (errno) {
goto value_error;
} else if (found && *(num) == 0) {
goto done;
} else if (found || num != p) {
goto check_tail_space;
} else {
goto value_error;
}
check_tail_space:
if (*(num) != 0) {
while (isspace((c = *(num++))));
if (c != 0) {
goto value_error;
}
}
done:
return (found ^ neg) - neg;
value_error:
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_ValueError, "invalid literal for int() with base %d: '%s'", (void*)(machine_uint_t)base, s));
//printf("invalid literal for int() with base %d: '%s'\n", base, s);
//return 0;
}
/*
int main(void) {
printf(" 0 %ld\n", strtonum("0", 0));
printf(" 1 %ld\n", strtonum("1", 0));
printf(" 1 %ld\n", strtonum("+1", 0));
printf(" -1 %ld\n", strtonum("-1", 0));
printf(" 0 %ld\n", strtonum("+0", 0));
printf(" 0 %ld\n", strtonum("-0", 0));
printf(" 1 %ld\n", strtonum("01", 0));
printf(" 9 %ld\n", strtonum("9", 0));
printf(" 10 %ld\n", strtonum("10", 0));
printf(" 10 %ld\n", strtonum("+10", 0));
printf("-10 %ld\n", strtonum("-10", 0));
printf(" 12 %ld\n", strtonum("12", 0));
printf("-12 %ld\n", strtonum("-12", 0));
printf(" 99 %ld\n", strtonum("99", 0));
printf("100 %ld\n", strtonum("100", 0));
printf("314 %ld\n", strtonum("314", 0));
printf("314 %ld\n", strtonum(" 314", 0));
printf("314 %ld\n", strtonum("314 ", 0));
printf("314 %ld\n", strtonum(" \t\t 314 \t\t ", 0));
printf(" 1 %ld\n", strtonum(" 1 ", 0));
printf(" -3 %ld\n", strtonum(" -3 ", 0));
printf(" 83 %ld\n", strtonum("0o123", 0));
printf(" 18 %ld\n", strtonum("0x12", 0));
printf(" 10 %ld\n", strtonum("0o12", 0));
printf(" 10 %ld\n", strtonum("0o12", 0));
printf(" 10 %ld\n", strtonum(" \t 0o12", 0));
printf(" 10 %ld\n", strtonum("0o12 \t ", 0));
printf(" 10 %ld\n", strtonum("0O12", 0));
printf(" 5 %ld\n", strtonum("0b101", 0));
printf(" 5 %ld\n", strtonum("0b101", 0));
printf(" 0 %ld\n", strtonum("0", 10));
printf(" 1 %ld\n", strtonum("1", 10));
printf(" 1 %ld\n", strtonum(" \t 1 \t ", 10));
printf(" 11 %ld\n", strtonum("11", 10));
printf(" 17 %ld\n", strtonum("11", 16));
printf(" 9 %ld\n", strtonum("11", 8));
printf(" 3 %ld\n", strtonum("11", 2));
printf(" 37 %ld\n", strtonum("11", 36));
printf("4294967296 %ld\n", strtonum("4294967296", 0));
printf("%ld\n", strtonum("x", 0));
printf("%ld\n", strtonum("1x", 0));
printf("%ld\n", strtonum(" 1x", 0));
printf("%ld\n", strtonum(" 1\02 ", 0));
printf("%ld\n", strtonum("", 0));
printf("%ld\n", strtonum(" ", 0));
printf("%ld\n", strtonum(" \t\t ", 0));
printf("%ld\n", strtonum("0x", 0));
printf("%ld\n", strtonum("0x", 16));
printf("%ld\n", strtonum("0o", 0));
printf("%ld\n", strtonum("0o", 8));
printf("%ld\n", strtonum("0b", 0));
printf("%ld\n", strtonum("0b", 2));
printf("%ld\n", strtonum("0b2", 2));
printf("%ld\n", strtonum("0o8", 8));
printf("%ld\n", strtonum("0xg", 16));
printf("%ld\n", strtonum("1 1", 0));
printf("%ld\n", strtonum("18446744073709551616", 0));
}
*/
#else /* defined(UNIX) */
long strtonum(const char *restrict s, int base) {
// TODO port strtol to stm
return 0;
}
#endif /* defined(UNIX) */
long strtonum(const char *restrict s, int base);
print(int(0))
print(int(1))
print(int(+1))
print(int(-1))
print(int('0'))
print(int('+0'))
print(int('-0'))
print(int('1'))
print(int('+1'))
print(int('-1'))
print(int('9'))
print(int('10'))
print(int('+10'))
print(int('-10'))
print(int('99'))
print(int('100'))
print(int('314'))
print(int(' 314'))
print(int('314 '))
print(int(' \t\t 314 \t\t '))
print(int(' 1 '))
print(int(' -3 '))
print(int('10', 16))
print(int('0o123', 0))
print(int('0x123', 16))
print(int('0X123', 16))
print(int('0O123', 8))
print(int('0B100', 2))
def test(value, base):
try:
print(int(value, base))
except ValueError:
print('ValueError')
test(' 1x', 0)
test(' 1\02 ', 0)
test('', 0)
test(' ', 0)
test(' \t\t ', 0)
test("\u0200", 0)
test('0x', 16)
test('0x', 0)
test('0o', 8)
test('0o', 0)
test('0b', 2)
test('0b', 0)
test('0b2', 2)
test('0o8', 8)
test('0xg', 16)
......@@ -11,7 +11,7 @@ ECHO = @echo
# compiler settings
CC = gcc
CFLAGS = -I. -I$(PY_SRC) -Wall -Werror -ansi -std=gnu99 -Os #-DNDEBUG
CFLAGS = -I. -I$(PY_SRC) -Wall -Werror -ansi -std=gnu99 -Os -DUNIX #-DNDEBUG
LDFLAGS = -lm
# source files
......
......@@ -11,7 +11,7 @@ ECHO = @echo
# compiler settings
CC = gcc
CFLAGS = -I. -I$(PY_SRC) -Wall -Werror -ansi -std=gnu99 -Os #-DNDEBUG
CFLAGS = -I. -I$(PY_SRC) -Wall -Werror -ansi -std=gnu99 -Os -DUNIX #-DNDEBUG
LDFLAGS = -lm
# source files
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment