mirror of
https://github.com/KarolS/millfork.git
synced 2025-03-13 01:30:55 +00:00
Forbid redefining builtins
This commit is contained in:
parent
e43fb39781
commit
36a0065b96
@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
* Extra `z` at the name of the encoding means that the string is zero-terminated.
|
* Extra `z` at the name of the encoding means that the string is zero-terminated.
|
||||||
|
|
||||||
|
* **Potentially breaking change!** No longer allowed to define things with names that are keywords or builtins.
|
||||||
|
|
||||||
* **Potentially breaking change!** Curly braces in text literals are now used for escape sequences.
|
* **Potentially breaking change!** Curly braces in text literals are now used for escape sequences.
|
||||||
|
|
||||||
* **Potentially breaking change!** Changed the `c64_basic` module.
|
* **Potentially breaking change!** Changed the `c64_basic` module.
|
||||||
|
30
src/main/scala/millfork/env/Environment.scala
vendored
30
src/main/scala/millfork/env/Environment.scala
vendored
@ -199,13 +199,20 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
|||||||
things ++= tagged
|
things ++= tagged
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var builtinsAdded: Boolean = false
|
||||||
val things: mutable.Map[String, Thing] = mutable.Map()
|
val things: mutable.Map[String, Thing] = mutable.Map()
|
||||||
|
val pointiesUsed: mutable.Map[String, Set[String]] = mutable.Map()
|
||||||
val removedThings: mutable.Set[String] = mutable.Set()
|
val removedThings: mutable.Set[String] = mutable.Set()
|
||||||
|
|
||||||
|
def isKnownPointy(callee: String, variable: String): Boolean = {
|
||||||
|
root.pointiesUsed.get(callee).exists(_.contains(variable))
|
||||||
|
}
|
||||||
|
|
||||||
private def addThing(t: Thing, position: Option[Position]): Unit = {
|
private def addThing(t: Thing, position: Option[Position]): Unit = {
|
||||||
assertNotDefined(t.name, position)
|
if (assertNotDefined(t.name, position)) {
|
||||||
things(t.name.stripPrefix(prefix)) = t
|
things(t.name.stripPrefix(prefix)) = t
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def removeVariable(str: String): Unit = {
|
def removeVariable(str: String): Unit = {
|
||||||
log.trace("Removing variable: " + str)
|
log.trace("Removing variable: " + str)
|
||||||
@ -387,11 +394,19 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
|||||||
BranchingOpcodeMapping(Opcode.BPL, IfFlagClear(ZFlag.S)),
|
BranchingOpcodeMapping(Opcode.BPL, IfFlagClear(ZFlag.S)),
|
||||||
BranchingOpcodeMapping(Opcode.BMI, IfFlagSet(ZFlag.S))),
|
BranchingOpcodeMapping(Opcode.BMI, IfFlagSet(ZFlag.S))),
|
||||||
None)
|
None)
|
||||||
|
builtinsAdded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
def assertNotDefined(name: String, position: Option[Position]): Unit = {
|
def assertNotDefined(name: String, position: Option[Position]): Boolean = {
|
||||||
if (things.contains(name) || parent.exists(_.things.contains(name)))
|
if (builtinsAdded && Environment.keywords(name)) {
|
||||||
log.fatal(s"`$name` is already defined", position)
|
log.error(s"Cannot redefine a builtin keyword `$name`", position)
|
||||||
|
false
|
||||||
|
} else if (things.contains(name) || parent.exists(_.things.contains(name))) {
|
||||||
|
log.error(s"`$name` is already defined", position)
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def registerType(stmt: TypeDefinitionStatement): Unit = {
|
def registerType(stmt: TypeDefinitionStatement): Unit = {
|
||||||
@ -1372,4 +1387,11 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
|||||||
|
|
||||||
object Environment {
|
object Environment {
|
||||||
val predefinedFunctions = Set("not", "hi", "lo", "nonet", "sizeof")
|
val predefinedFunctions = Set("not", "hi", "lo", "nonet", "sizeof")
|
||||||
|
val keywords: Set[String] = Set(
|
||||||
|
"true", "false",
|
||||||
|
"byte", "sbyte", "word", "pointer", "void", "long",
|
||||||
|
"array", "const", "alias", "import", "static", "register", "stack", "volatile", "asm", "extern", "kernal_interrupt", "interrupt",
|
||||||
|
"for", "if", "do", "while", "else", "return", "default", "to", "until", "paralleluntil", "parallelto", "downto",
|
||||||
|
"inline", "noinline"
|
||||||
|
) ++ predefinedFunctions
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ class SeparateBytesSuite extends FunSuite with Matchers {
|
|||||||
|
|
||||||
test("Magic split array") {
|
test("Magic split array") {
|
||||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)("""
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)("""
|
||||||
| array hi [16] @$c000
|
| array high [16] @$c000
|
||||||
| array lo [16] @$c010
|
| array low [16] @$c010
|
||||||
| void main () {
|
| void main () {
|
||||||
| word a
|
| word a
|
||||||
| word b
|
| word b
|
||||||
@ -86,7 +86,7 @@ class SeparateBytesSuite extends FunSuite with Matchers {
|
|||||||
| byte i
|
| byte i
|
||||||
| i = 0
|
| i = 0
|
||||||
| while i < 16 {
|
| while i < 16 {
|
||||||
| hi[i]:lo[i] = a
|
| high[i]:low[i] = a
|
||||||
| tmp = a
|
| tmp = a
|
||||||
| tmp += b
|
| tmp += b
|
||||||
| a = b
|
| a = b
|
||||||
|
Loading…
x
Reference in New Issue
Block a user