mirror of
https://github.com/piotr-wiszowaty/foco65.git
synced 2024-12-17 20:30:12 +00:00
Declare constants and variables directly in assembly output
This commit is contained in:
parent
3129056a48
commit
6a255534df
96
foco65
96
foco65
@ -147,8 +147,11 @@ class Code:
|
||||
self.code = code
|
||||
self.section = section
|
||||
|
||||
def __str__(self):
|
||||
return self.code[1:] + "\n"
|
||||
def output(self, section):
|
||||
if section == self.section:
|
||||
return self.code[1:] + "\n"
|
||||
else:
|
||||
return ""
|
||||
|
||||
#####
|
||||
|
||||
@ -166,8 +169,8 @@ class Word:
|
||||
self.recursive = False
|
||||
self.used = False
|
||||
|
||||
def __str__(self):
|
||||
if self.used:
|
||||
def output(self, section):
|
||||
if self.used and self.section == section:
|
||||
if self.code:
|
||||
return "%s\n dta a(*+2)\n%s\n" % (self.label, self.code)
|
||||
else:
|
||||
@ -189,23 +192,47 @@ class Word:
|
||||
|
||||
#####
|
||||
|
||||
class Constant:
|
||||
def __init__(self, name, label, value, section):
|
||||
class RefBase:
|
||||
def __init__(self, name, label, value, text_section, data_section):
|
||||
self.name = name
|
||||
self.label = label
|
||||
self.value = value
|
||||
self.section = section
|
||||
self.text_section = text_section
|
||||
self.data_section = data_section
|
||||
self.used = False
|
||||
|
||||
def __str__(self):
|
||||
def output(self, section):
|
||||
if self.used:
|
||||
return "%s\n dta a(const),a(%s)\n" % (self.label, self.value)
|
||||
if section == self.text_section:
|
||||
return self.text_output
|
||||
elif section == self.data_section:
|
||||
return self.data_output
|
||||
else:
|
||||
return ""
|
||||
else:
|
||||
return ""
|
||||
|
||||
def __iter__(self):
|
||||
return iter([])
|
||||
|
||||
|
||||
class Constant(RefBase):
|
||||
def __init__(self, name, label, value, text_section, data_section):
|
||||
RefBase.__init__(self, name, label, value, text_section, data_section)
|
||||
self.label = "const_" + label
|
||||
self.text_output = "%s\n dta a(const),a(%s)\n" % (self.label, label)
|
||||
self.data_output = "%s equ %s\n" % (label, self.value)
|
||||
|
||||
|
||||
class Variable(RefBase):
|
||||
def __init__(self, name, label, size, text_section, data_section):
|
||||
RefBase.__init__(self, name, label, None, text_section, data_section)
|
||||
self.label = "var_" + label
|
||||
self.text_output = "%s\n dta a(const),a(%s)\n" % (self.label, label)
|
||||
if size:
|
||||
self.data_output = "%s equ *\n org *+%d\n" % (label, 2*size)
|
||||
else:
|
||||
self.data_output = "%s equ *\n" % label
|
||||
|
||||
#####
|
||||
|
||||
class BranchTarget:
|
||||
@ -250,7 +277,8 @@ class Forth:
|
||||
self.words = Words()
|
||||
self.items = []
|
||||
self.sections = sections
|
||||
self.section = "code"
|
||||
self.text_section = "text"
|
||||
self.data_section = "data"
|
||||
self.stack = []
|
||||
self.do_loop_stack = []
|
||||
self.int_prog = re.compile("-?[0-9]+")
|
||||
@ -323,12 +351,14 @@ class Forth:
|
||||
token = self.next()
|
||||
if token == ":":
|
||||
token = self.next()
|
||||
self.word = Word(token.text, self.section, label=token.canon())
|
||||
self.word = Word(token.text, self.text_section, label=token.canon())
|
||||
self.set_state("compile")
|
||||
elif token == "[code]":
|
||||
self.items.append(self.parse_code())
|
||||
elif token == "[section]":
|
||||
self.parse_section()
|
||||
elif token == "[text-section]":
|
||||
self.text_section = self.parse_section()
|
||||
elif token == "[data-section]":
|
||||
self.data_section = self.parse_section()
|
||||
elif token == "variable":
|
||||
self.parse_variable(1)
|
||||
elif token == "2variable":
|
||||
@ -370,7 +400,7 @@ class Forth:
|
||||
self.push(x1 / x2)
|
||||
elif token == "]":
|
||||
self.word.add("lit")
|
||||
self.word.add(str(self.pop(token)))
|
||||
self.word.add(self.pop(token).output(self.text_section))
|
||||
self.set_state("compile")
|
||||
elif self.isnumber(token):
|
||||
self.push(self.tonumber(token.text))
|
||||
@ -485,50 +515,42 @@ class Forth:
|
||||
self.input.mark_end()
|
||||
token = self.next()
|
||||
if token == "[end-code]":
|
||||
return Code(self.input.marked(), self.section)
|
||||
return Code(self.input.marked(), self.text_section)
|
||||
|
||||
def parse_section(self):
|
||||
token = self.next()
|
||||
self.section = token.text
|
||||
return token.text
|
||||
|
||||
def parse_variable(self, size):
|
||||
token = self.next()
|
||||
name = token.text
|
||||
label = token.canon()
|
||||
value = "var_" + token.canon()
|
||||
word = Constant(name, label, value, self.section)
|
||||
word = Variable(name, label, size, self.text_section, self.data_section)
|
||||
self.add_word(word)
|
||||
if size == 1:
|
||||
self.items.append(Code("\n%s\n dta a(0)\n" % value, "data"))
|
||||
elif size == 2:
|
||||
self.items.append(Code("\n%s\n dta a(0),a(0)\n" % value, "data"))
|
||||
|
||||
def parse_constant(self, token):
|
||||
token = self.next()
|
||||
num = self.pop(token)
|
||||
word = Constant(token.text, token.canon(), num, self.section)
|
||||
word = Constant(token.text, token.canon(), num, self.text_section, self.data_section)
|
||||
self.add_word(word)
|
||||
|
||||
def parse_create(self):
|
||||
token = self.next()
|
||||
name = token.text
|
||||
label = token.canon()
|
||||
value = "var_" + token.canon()
|
||||
word = Constant(name, label, value, self.section)
|
||||
word = Variable(name, label, 0, self.text_section, self.data_section)
|
||||
self.add_word(word)
|
||||
self.items.append(Code("\n%s" % value, "data"))
|
||||
|
||||
def parse_allot(self, token):
|
||||
count = self.pop(token)
|
||||
zeros = ",".join(["0"] * count)
|
||||
self.items.append(Code("\n dta %s" % zeros, "data"))
|
||||
self.items.append(Code("\n org *+%d" % count, self.data_section))
|
||||
|
||||
def parse_comma(self, token):
|
||||
item = Code("\n dta a(%d)" % self.pop(token), "data")
|
||||
item = Code("\n dta a(%d)" % self.pop(token), self.data_section)
|
||||
self.items.append(item)
|
||||
|
||||
def parse_c_comma(self, token):
|
||||
item = Code("\n dta %d" % self.pop(token), "data")
|
||||
item = Code("\n dta %d" % self.pop(token), self.data_section)
|
||||
self.items.append(item)
|
||||
|
||||
def parse_comma_doublequote(self):
|
||||
@ -539,7 +561,7 @@ class Forth:
|
||||
if token.endswith('"'):
|
||||
self.input.mark_end()
|
||||
text = self.input.marked()[1:-1]
|
||||
item = Code("\n dta %d,c'%s'" % (len(text), text), "data")
|
||||
item = Code("\n dta %d,c'%s'" % (len(text), text), self.data_section)
|
||||
self.items.append(item)
|
||||
break
|
||||
|
||||
@ -560,7 +582,7 @@ class Forth:
|
||||
count = "%d," % len(text)
|
||||
else:
|
||||
count = ""
|
||||
item = Code("\n dta %sd'%s'%s" % (count, text, inverse), "data")
|
||||
item = Code("\n dta %sd'%s'%s" % (count, text, inverse), self.data_section)
|
||||
self.items.append(item)
|
||||
break
|
||||
|
||||
@ -578,15 +600,15 @@ class Forth:
|
||||
raise StackNotEmpty(self.input.line, self.input.column)
|
||||
section_outputs = []
|
||||
for section in self.sections:
|
||||
item_outputs = map(str, filter(lambda i: i.section == section, self.items))
|
||||
section_outputs.append("; section %s\n" % section)
|
||||
item_outputs = map(lambda i: i.output(section), self.items)
|
||||
section_outputs.append("".join(item_outputs))
|
||||
return "\n".join(section_outputs)
|
||||
|
||||
#####
|
||||
|
||||
boot_text = """
|
||||
[section] boot
|
||||
[text-section] boot
|
||||
|
||||
[code]
|
||||
ip equ $80
|
||||
@ -764,7 +786,7 @@ until_end
|
||||
"""
|
||||
|
||||
basewords_text = """
|
||||
[section] code
|
||||
[text-section] code
|
||||
|
||||
: drop
|
||||
[code]
|
||||
@ -1790,7 +1812,7 @@ m_star_done
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--sections", "-s", metavar="STR", default="init,boot,data,code")
|
||||
parser.add_argument("--sections", "-s", metavar="STR", default="init,boot,data,text")
|
||||
parser.add_argument("--pstack-bottom", "-p", metavar="ADDR", default="$600")
|
||||
parser.add_argument("--pstack-size", "-S", metavar="NUM", default=256, type=int)
|
||||
parser.add_argument("file", metavar="FILE")
|
||||
|
Loading…
Reference in New Issue
Block a user