I hope you'll continue messing around with Python. I borrowed your approach on the assembler code and started the project of a very simple and basic parser generator. My previous attempts didn't go well so I have to thank you because this time it worked as expected.
Since the erased flash memory holds the values of 0xFF, it would probably be better to pad the unused areas with 0xFF instead of 0x00 - it may make the flash programming faster. It can also be defined by a command-line argument.
Very nice! What you might want next is labels (for neater jumps) and macros (so you don't have to repeat yourself all the time). But maybe a little different approach to the assembler would make it easier to expand. As it is now you have to declare new operands, arguments, etc. And after that you need to write how to parse those things, how to print them and how to encode them. Maybe instead of matching a string like "if self.consume_identifier("ldi"): do_stuff" you could take the string as an argument and use a dictionary? Eg. "mv": [symbol, argument_type, ...]. Data in this dictionary could then be interpreted by functions (to parse, print, encode) to automagicaly do the things that you have to add manually. This way instead of updating your code in several places when adding new opcodes you would just expand the LUT and rest of the code would stay as it was. Maybe it would even parse larger files faster in the future because it might end up with less if statements to check? I'm not a programmer (just a PLC wrangler), not a python guru and certainly not a parsing expert, so take it with a grain of salt, but I believe this might be a good improvement.
That's a great suggestion! The parsing, printing, and encoding is highly repetitive, and there are only 3 or 4 distinct instruction formats. I'll definitely move to a table-based approach in the future 🙂
Very interesting. Right now it's a smaller program, but have you tested how the assembler fares for much larger programs in terms of build speed? Maybe something like a full 128KB program?
Thanks! 🙂 Right now it should be fairly quick. Since the assembler doesn't do anything fancy yet, and it just runs through the instructions three times, runtime should scale linearly with the input program size. Python has weird performance cliffs and behavior though, so this assembler isn't going to beat speed records 😏
Very cool. I am wondering if it could be made as a standalone .exe that you can run. That way, you could just run the program and have all the parsing and output code hidden away. Also looking forward to getting back to some hardware. Will be interesting to see if you approached it in a similar way to me, particularly the bitwise logic/shift...
The way you add onto strings within a loop (buffer += bytes(...)) is accidentally quadratic. Every time you append a new thing to the end of a string, you have to allocate a whole new string. This will start to bite with bigger programs. You should use bytearray or a list which you b"".join() at the end.
I hope you'll continue messing around with Python.
I borrowed your approach on the assembler code and started the project of a very simple and basic parser generator. My previous attempts didn't go well so I have to thank you because this time it worked as expected.
Cool, that sounds exciting! Glad to hear that you were successful 🙂👍
Heck yeah man! You gotta get your start somewhere!
brilliant my dude!
Thanks 🙂
Since the erased flash memory holds the values of 0xFF, it would probably be better to pad the unused areas with 0xFF instead of 0x00 - it may make the flash programming faster. It can also be defined by a command-line argument.
Great idea! I'm curious whether the programmer and flash chip I'm using are smart enough to skip erases on blocks that are already 0xFF everywhere.
Very nice! What you might want next is labels (for neater jumps) and macros (so you don't have to repeat yourself all the time).
But maybe a little different approach to the assembler would make it easier to expand.
As it is now you have to declare new operands, arguments, etc. And after that you need to write how to parse those things, how to print them and how to encode them.
Maybe instead of matching a string like "if self.consume_identifier("ldi"): do_stuff" you could take the string as an argument and use a dictionary?
Eg. "mv": [symbol, argument_type, ...].
Data in this dictionary could then be interpreted by functions (to parse, print, encode) to automagicaly do the things that you have to add manually.
This way instead of updating your code in several places when adding new opcodes you would just expand the LUT and rest of the code would stay as it was.
Maybe it would even parse larger files faster in the future because it might end up with less if statements to check?
I'm not a programmer (just a PLC wrangler), not a python guru and certainly not a parsing expert, so take it with a grain of salt, but I believe this might be a good improvement.
That's a great suggestion! The parsing, printing, and encoding is highly repetitive, and there are only 3 or 4 distinct instruction formats. I'll definitely move to a table-based approach in the future 🙂
Very interesting. Right now it's a smaller program, but have you tested how the assembler fares for much larger programs in terms of build speed? Maybe something like a full 128KB program?
Thanks! 🙂 Right now it should be fairly quick. Since the assembler doesn't do anything fancy yet, and it just runs through the instructions three times, runtime should scale linearly with the input program size. Python has weird performance cliffs and behavior though, so this assembler isn't going to beat speed records 😏
Very cool. I am wondering if it could be made as a standalone .exe that you can run. That way, you could just run the program and have all the parsing and output code hidden away.
Also looking forward to getting back to some hardware. Will be interesting to see if you approached it in a similar way to me, particularly the bitwise logic/shift...
ALU is coming up next 🙂
That would be pretty interesting...
are you going to add labels?
Yes, that's on my todo list. My plan is to do a second round of coding on the assembler to add expressions, more directives, and labels. 🙂
The way you add onto strings within a loop (buffer += bytes(...)) is accidentally quadratic. Every time you append a new thing to the end of a string, you have to allocate a whole new string. This will start to bite with bigger programs. You should use bytearray or a list which you b"".join() at the end.
Excellent point! 👍 I'll fix that 🙂