mirror of
https://github.com/KarolS/millfork.git
synced 2024-11-18 22:07:07 +00:00
Allow text literals in more positions
This commit is contained in:
parent
bb5c633172
commit
8922beda00
@ -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() {
|
||||
|
@ -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)
|
||||
|
15
src/main/scala/millfork/env/Environment.scala
vendored
15
src/main/scala/millfork/env/Environment.scala
vendored
@ -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)) {
|
||||
|
@ -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 =>
|
||||
|
Loading…
Reference in New Issue
Block a user