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