John West wrote:
There is one trap to watch out for though - if you have a two pass assembler, and a symbol that's defined after it is used, the first pass will have to assume that it's 16 bit. If it later turns out to fit in 8 bits, you can't change your mind without invalidating every label after that first use...It will never shrink a two byte value to one byte, so it's guaranteed to converge eventually.
This is where I stopped on my assembler project. Hmm, interesting. Do you think it happens often in practice that an 8 bit symbol becomes 16 bit but could be shrunk back to 8 bit after other symbols are resolved? My plan is to do that but fail after a certain number of passes. Another way might be to monitor the sizes of symbols and try to detect the situation where the size oscillates indefinitely. Your way seems reliable and maybe that should be an option or the back up method.
Quote:
As an aside: HIGH vs HI vs > vs LOW vs LO vs < ?
Just my 2 cents but how about < and > since those can be wrapped in a HI or LO macro? Depending on how you have your macros set up, it might not accept < as a macro name that can be mapped to LO.
What language are you using for the assembler? In Python it was really easy to set up functions like the following and let users add their own functions, which is about as powerful as an assembler could ever get (assuming of course you're not averse to having to include a custom Python file in your project source.)
Code:
def left(arg1,arg2): return arg1[0:int(arg2)]
def right(arg1,arg2): return arg1[-int(arg2):]
def hi(arg1): return (int(arg1)>>8)&0xFF
def lo(arg1): return int(arg1)&0xFF
def concat(arg1,arg2): return arg1+arg2
def substr(arg1,arg2,arg3): return arg1[int(arg2):int(arg3)]
def lower(arg1): return arg1.lower()
def upper(arg1): return arg1.upper()
def to_int(arg1): return int(float(arg1))
#text name of function, number of arguments, function
commandlist=[('left',2,left),
('right',2,right),
('hi',1,hi),
('lo',1,lo),
('concat',2,concat),
('substr',3,substr),
#('lower',1,lower),
#Alternately, define the function inline
('lower',1,lambda arg1: arg1.lower()),
('upper',1,upper),
#Built in functions
('int',1,to_int),
('float',1,float),
#These change type and need to be handled in the main program
('alpha',1,0),
('str',1,0),
('char',1,0),
#ADD CUSTOM FUNCTIONS HERE:
#example(x,y) = x+2*y
('example',2,lambda x,y:int(x)+int(y)*2)]