diff --git a/Makefile b/Makefile index dc6c3c2..343c3a4 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,7 @@ +asm/libcreole.so: creole.c creole.h + $(CC) -Wall -fPIC -c creole.c -o c_test/creole.o + $(CC) -shared -o asm/libcreole.so c_test/creole.o + c_test/encode_decode: c_test/encode_decode.c creole.c creole.h $(CC) c_test/encode_decode.c -Wall -pedantic -std=c89 -g -fopenmp -o c_test/encode_decode c_test/creole: c_test/creole.c creole.c creole.h greatest.h diff --git a/asm/creole_asm.py b/asm/creole.py similarity index 100% rename from asm/creole_asm.py rename to asm/creole.py diff --git a/asm/ffi.py b/asm/ffi.py new file mode 100644 index 0000000..87f6275 --- /dev/null +++ b/asm/ffi.py @@ -0,0 +1,29 @@ +from ctypes import * +dll = CDLL("./libcreole.so") + +class CIns(Structure): + _fields_ = [("opcode", c_int), + ("w_flags", c_ubyte * 3), + ("w", c_uint * 3)] + +class CReader(Structure): + _fields_ = [("p", POINTER(c_ubyte)), + ("left", c_size_t)] +def make_uchar_buf(s): + buf = (c_ubyte * len(s))() + buf[:] = s[:] + return buf + +class CParseLineException(Exception): + pass +def parse_line(line): + buf = make_uchar_buf(line) + + rd = CReader(buf, len(line)) + ins = CIns() + + ret = dll.creole_parse_line(byref(ins), byref(rd)) + + if ret != 0: + raise CParseLineException(ret) + return (ins.opcode, list(zip(ins.w_flags, ins.w))) diff --git a/asm/test.py b/asm/test.py index e86b508..dc07655 100644 --- a/asm/test.py +++ b/asm/test.py @@ -1,5 +1,6 @@ from creole import * import unittest +import ffi class ProgramTest(unittest.TestCase): def test_oneline(self): @@ -38,5 +39,12 @@ class ProgramTest(unittest.TestCase): b = p() self.assertEqual(b, b_ex) + def test_parse_reg(self): + p = Program() + p.parse_asm_line("push r5") + ins = ffi.parse_line(p()) + self.assertEqual(ins[0], instructions["push"].opcode) + self.assertEqual(ins[1][0], (1,5)) + if __name__ == "__main__": unittest.main() diff --git a/c_test/creole.c b/c_test/creole.c index 5f73cd6..de735c1 100644 --- a/c_test/creole.c +++ b/c_test/creole.c @@ -37,66 +37,6 @@ SUITE(reader) { RUN_TEST1(reader_test_basic, &r); } -#if 0 -TEST encode_decode_byte_seq(struct seq *s) { - unsigned char buf[7]; - struct creole_reader r = {0}; - struct word w; - creole_word i = 0; - - for (;;) { - ASSERT_EQ(creole_encode(i, s->encode_to, s->high_bits, - buf), 1); - r.p = buf; - r.left = s->encode_to; - ASSERT_EQ(decode_seq(&r, &w), 1); - ASSERT_EQ(w.len, s->encode_to); - ASSERT_EQ(w.high_bits, s->high_bits); - ASSERT_EQ(w.word, i); - - if (i == s->max) - break; - i++; - } - - PASS(); -} -SUITE(pseudo_utf8_encode_all) { - struct seq s; - - s.max = 0x7F; - s.encode_to = 1; - s.high_bits = 0; - RUN_TEST1(encode_decode_byte_seq, &s); - - for (s.high_bits = 0; s.high_bits < 16; s.high_bits++) { - s.max = 0x7F; - s.encode_to = 2; - RUN_TEST1(encode_decode_byte_seq, &s); - - s.max = 0xFFF; - s.encode_to = 3; - RUN_TEST1(encode_decode_byte_seq, &s); - - s.max = 0x1FFFF; - s.encode_to = 4; - RUN_TEST1(encode_decode_byte_seq, &s); - - s.max = 0x3FFFFF; - s.encode_to = 5; - RUN_TEST1(encode_decode_byte_seq, &s); - - s.max = 0x7FFFFFF; - s.encode_to = 6; - RUN_TEST1(encode_decode_byte_seq, &s); - - s.max = 0xFFFFFFFF; - s.encode_to = 7; - RUN_TEST1(encode_decode_byte_seq, &s); - } -} -#endif - int main(int argc, char *argv[]) { GREATEST_MAIN_BEGIN(); RUN_SUITE(reader); diff --git a/creole.c b/creole.c index d29d25c..d2a06cb 100644 --- a/creole.c +++ b/creole.c @@ -304,8 +304,6 @@ int creole_encode(creole_word i, unsigned encode_to, unsigned high_bits, return 1; } -#if 0 - /************************************************************************* * Parsing instructions * @@ -315,34 +313,37 @@ int creole_encode(creole_word i, unsigned encode_to, unsigned high_bits, * one single byte of all zeros. *************************************************************************/ -int creole_parse_line(struct creole_ins *ins, struct creole_reader *r) +enum creole_compiler_ret +creole_parse_line(struct creole_ins *ins, struct creole_reader *r) { struct word w = {0}; unsigned arg = 0; if (!decode_seq(r, &w)) - return 0; + return CREOLE_OPCODE_READ_ERROR; ins->opcode = w.word; - if (w.word < CREOLE_ARG_TYPE_LEN || w.len != 1) - return 0; + if (w.word >= CREOLE_ARG_TYPE_LEN || w.len != 1) + return CREOLE_OPCODE_MALFORMED; - for (arg = 0; arg < arglen; arg++) { + for (arg = 0; arg < opcode_info[ins->opcode].arglen; arg++) { if (!decode_seq(r, &w)) - return 0; + return CREOLE_ARG_READ_ERROR; if (w.len == 1) - return 0; + return CREOLE_ARG_MALFORMED; ins->w[arg] = w.word; ins->w_flags[arg] = w.high_bits; } if (!decode_seq(r, &w)) - return 0; + return CREOLE_LAST_READ_ERROR; if (w.word != 0 || w.len != 1) - return 0; - return 1; + return CREOLE_LAST_MALFORMED; + return CREOLE_COMPILE_OK; } +#if 0 + /************************************************************************** * High level compiling interface *************************************************************************/ diff --git a/creole.h b/creole.h index 579f787..da6b662 100644 --- a/creole.h +++ b/creole.h @@ -34,7 +34,12 @@ enum creole_word_flag { enum creole_compiler_ret { CREOLE_COMPILE_OK, - CREOLE_COMPILE_PARSE_ERROR, + CREOLE_OPCODE_READ_ERROR, + CREOLE_OPCODE_MALFORMED, + CREOLE_ARG_READ_ERROR, + CREOLE_ARG_MALFORMED, + CREOLE_LAST_READ_ERROR, + CREOLE_LAST_MALFORMED, CREOLE_LABEL_OVERFLOW, CREOLE_TYPE_ERROR, CREOLE_COMPILE_RET_LEN @@ -65,4 +70,9 @@ struct creole_reader { size_t left; }; +int creole_encode(creole_word i, unsigned encode_to, unsigned high_bits, + unsigned char buf[7]); +enum creole_compiler_ret +creole_parse_line(struct creole_ins *ins, struct creole_reader *r); + #endif /* CREOLE_H */