1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-06-25 19:29:49 +00:00

Allow text literals in more positions

This commit is contained in:
Karol Stasiak 2019-07-27 01:38:06 +02:00
parent bb5c633172
commit 8922beda00
4 changed files with 27 additions and 20 deletions

View File

@ -9,13 +9,9 @@ struct stage {
pointer text
}
// can't put text literals directly in struct constructors yet
array fizz = "fizz"z
array buzz = "buzz"z
array(stage) stages = [
stage(divisible3.pointer, fizz),
stage(divisible5.pointer, buzz)
stage(divisible3.pointer, "fizz"z),
stage(divisible5.pointer, "buzz"z)
]
void main() {

View File

@ -250,14 +250,6 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
}
}
def genName(characters: List[Expression]): String = {
"textliteral$" ++ characters.flatMap{
case LiteralExpression(n, _) =>
f"$n%02x"
case _ => ???
}
}
def optimizeExpr(expr: Expression, currentVarValues: VV): Expression = {
val pos = expr.position
// stdlib:
@ -448,11 +440,8 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
DerefExpression(optimizeExpr(inner, currentVarValues), 0, env.get[VariableType]("byte")).pos(pos)
case DerefDebuggingExpression(inner, 2) =>
DerefExpression(optimizeExpr(inner, currentVarValues), 0, env.get[VariableType]("word")).pos(pos)
case TextLiteralExpression(characters) =>
val name = genName(characters)
if (ctx.env.maybeGet[Thing](name).isEmpty) {
ctx.env.root.registerArray(ArrayDeclarationStatement(name, None, None, "byte", None, const = true, Some(LiteralContents(characters)), None).pos(pos), ctx.options)
}
case e@TextLiteralExpression(characters) =>
val name = ctx.env.getTextLiteralArrayName(e)
VariableExpression(name).pos(pos)
case VariableExpression(v) if currentVarValues.contains(v) =>
val constant = currentVarValues(v)

View File

@ -599,7 +599,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
private def evalImpl(e: Expression, vv: Option[Map[String, Constant]]): Option[Constant] = {
e match {
case LiteralExpression(value, size) => Some(NumericConstant(value, size))
case _:TextLiteralExpression => ???
case tl:TextLiteralExpression => Some(getPointy(getTextLiteralArrayName(tl)).asInstanceOf[ConstantPointy].value)
case ConstantArrayElementExpression(c) => Some(c)
case GeneratedConstantExpression(c, t) => Some(c)
case VariableExpression(name) =>
@ -1160,6 +1160,19 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
get[Type]("function." + p.name + ".to." + f.returnType.name)
}
def getTextLiteralArrayName(literal: TextLiteralExpression): String = {
val name = "textliteral$" ++ literal.characters.flatMap {
case LiteralExpression(n, _) =>
f"$n%02x"
case _ => ???
}
if (maybeGet[Thing](name).isEmpty) {
println("registering text literal")
root.registerArray(ArrayDeclarationStatement(name, None, None, "byte", None, const = true, Some(LiteralContents(literal.characters)), None).pos(literal.position), options)
}
name
}
private def registerAddressConstant(thing: ThingInMemory, position: Option[Position], options: CompilationOptions, targetType: Option[Type]): Unit = {
val b = get[Type]("byte")
if (!thing.zeropage && options.flag(CompilationFlag.LUnixRelocatableCode)) {

View File

@ -339,6 +339,15 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
case _ =>
}
// force early allocation of text literals:
env.allPreallocatables.filterNot(o => unusedRuntimeObjects(o.name)).foreach{
case thing@InitializedArray(_, _, items, _, _, _, _, _) =>
items.foreach(env.eval(_))
case InitializedMemoryVariable(_, _, _, value, _, _, _) =>
env.eval(value)
case _ =>
}
if (options.flag(CompilationFlag.LUnixRelocatableCode)) {
env.allThings.things.foreach {
case (_, m@UninitializedMemoryVariable(name, typ, _, _, _, _)) if name.endsWith(".addr") || env.maybeGet[Thing](name + ".array").isDefined =>