mirror of
https://github.com/KarolS/millfork.git
synced 2025-02-06 01:30:13 +00:00
Document keywords and handle them better
This commit is contained in:
parent
3d3089ee93
commit
c61d044226
@ -36,6 +36,8 @@
|
||||
|
||||
* [Important guidelines regarding reentrancy](lang/reentrancy.md)
|
||||
|
||||
* [List of keywords](lang/keywords.md)
|
||||
|
||||
## Library reference
|
||||
|
||||
* [`stdlib` module](stdlib/stdlib.md)
|
||||
|
@ -36,6 +36,8 @@
|
||||
|
||||
* [Important guidelines regarding reentrancy](lang/reentrancy.md)
|
||||
|
||||
* [List of keywords](lang/keywords.md)
|
||||
|
||||
## Library reference
|
||||
|
||||
* [`stdlib` module](stdlib/stdlib.md)
|
||||
|
113
docs/lang/keywords.md
Normal file
113
docs/lang/keywords.md
Normal file
@ -0,0 +1,113 @@
|
||||
[< back to index](../doc_index.md)
|
||||
|
||||
# List of keywords
|
||||
|
||||
## Normal keywords
|
||||
|
||||
### Top level keywords
|
||||
|
||||
These keywords can occur at the top level of the file:
|
||||
|
||||
import segment
|
||||
array struct union enum alias
|
||||
|
||||
### Declaration modifiers
|
||||
|
||||
These keywords occur within variable, array and function declarations:
|
||||
|
||||
* Variable declaration modifiers: `const volatile register static stack`
|
||||
|
||||
* Function declaration modifiers: `asm inline noinline interrupt kernal_interrupt macro reentrant extern`
|
||||
|
||||
* Array declaration modifiers: `const`
|
||||
|
||||
* Common modifiers: `segment align`
|
||||
|
||||
### Statement keywords
|
||||
|
||||
These keywords occur within function bodies:
|
||||
|
||||
if else for while do
|
||||
goto label
|
||||
asm
|
||||
return
|
||||
|
||||
### Sub-statement keywords
|
||||
|
||||
These keywords occur within bodies of certain other statements:
|
||||
|
||||
* for-loop directions: `to until downto parallelto parallel until`
|
||||
|
||||
* special return-dispatch branch: `default`
|
||||
|
||||
* loop control flow: `break continue`
|
||||
|
||||
## Contextual keywords
|
||||
|
||||
These are not considered keywords, but have special meaning in certain syntactical locations:
|
||||
|
||||
* special alignment constant: `fast`
|
||||
|
||||
* special array function: `file`
|
||||
|
||||
* text encoding names: `z defaultz scr scrz`; for the rest, see [the list of text encodings](./text.md)
|
||||
`default` is also a name of a text encoding, but it's also a keyword
|
||||
|
||||
## Reserved identifiers
|
||||
|
||||
Most of reserved identifiers are considered keywords (i.e. you cannot override them, even locally).
|
||||
Some are not, but overriding them is strongly discouraged and for highest code clarity should also be considered keywords.
|
||||
|
||||
The keyword status of those identifiers may change in the future.
|
||||
|
||||
### Built-in types
|
||||
|
||||
The following identifiers are considered keywords:
|
||||
|
||||
byte ubyte sbyte word long
|
||||
pointer void bool
|
||||
set_carry set_zero set_overflow set_negative
|
||||
clear_carry clear_zero clear_overflow clear_negative
|
||||
int16 int24 int32 int40 int 48 int56 int64 int72 int80 int88 int96 int104 int112 int120 int128
|
||||
unsigned8 signed8
|
||||
|
||||
`farword` is a deprecated alias for `int24` and it is not a keyword. It will be removed in the future.
|
||||
|
||||
### Built-in constants
|
||||
|
||||
The following identifiers are considered keywords:
|
||||
|
||||
true false
|
||||
|
||||
The following identifiers are not considered keywords:
|
||||
|
||||
nullptr nullchar
|
||||
|
||||
### Built-in functions and operators
|
||||
|
||||
The following identifiers are considered keywords:
|
||||
|
||||
not hi lo nonet sizeof
|
||||
|
||||
The following identifiers are not considered keywords:
|
||||
|
||||
sin cos tan call
|
||||
|
||||
## Reserved field names
|
||||
|
||||
It is not allowed to define a struct or a union with a field with any of the following names:
|
||||
|
||||
pointer addr rawaddr return
|
||||
|
||||
## Preprocesor keywords
|
||||
|
||||
### Directives
|
||||
|
||||
#if #elseif #else #endif
|
||||
#define #use
|
||||
#pragma
|
||||
#fatal #error #warn #info #infoeval
|
||||
|
||||
### Built-in functions
|
||||
|
||||
not hi lo defined if
|
@ -30,6 +30,7 @@ nav:
|
||||
- Inline 6502 assembly: lang/assembly.md
|
||||
- Inline 8080/LR35902/Z80 assembly: lang/assemblyz80.md
|
||||
- Reentrancy guidelines: lang/reentrancy.md
|
||||
- List of keywords: lang/keywords.md
|
||||
- Library reference:
|
||||
- stdlib module: stdlib/stdlib.md
|
||||
- string module: stdlib/string.md
|
||||
|
37
src/main/scala/millfork/env/Environment.scala
vendored
37
src/main/scala/millfork/env/Environment.scala
vendored
@ -505,8 +505,14 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
}
|
||||
|
||||
def assertNotDefined(name: String, position: Option[Position]): Boolean = {
|
||||
if (builtinsAdded && Environment.keywords(name)) {
|
||||
log.error(s"Cannot redefine a builtin keyword `$name`", position)
|
||||
if (builtinsAdded && Environment.invalidNewIdentifiers(name)) {
|
||||
if (Environment.predefinedFunctions(name)) {
|
||||
log.error(s"Cannot redefine a builtin predefined function `$name`", position)
|
||||
} else if (Environment.neverIdentifiers(name)) {
|
||||
log.error(s"Cannot the keyword `$name` as a name", position)
|
||||
} else if (Environment.invalidNewIdentifiers(name)) {
|
||||
log.error(s"Cannot redefine a builtin predefined identifier `$name`", position)
|
||||
}
|
||||
false
|
||||
} else if (things.contains(name) || parent.exists(_.things.contains(name)) || things.contains(name.stripPrefix(prefix))) {
|
||||
if (!name.contains('.')){
|
||||
@ -2120,13 +2126,30 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
}
|
||||
|
||||
object Environment {
|
||||
// built-in special-cased functions; can be considered keywords by some:
|
||||
val predefinedFunctions: Set[String] = 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",
|
||||
// built-in special-cased functions, not keywords, but assumed to work almost as such:
|
||||
val specialFunctions: Set[String] = Set("sin", "cos", "tan", "call")
|
||||
// keywords:
|
||||
val neverIdentifiers: Set[String] = Set(
|
||||
"array", "const", "alias", "import", "static", "register", "stack", "volatile", "asm", "extern", "kernal_interrupt", "interrupt", "reentrant", "segment",
|
||||
"struct", "union", "enum",
|
||||
"for", "if", "do", "while", "else", "return", "default",
|
||||
"to", "until", "paralleluntil", "parallelto", "downto",
|
||||
"break", "continue",
|
||||
"inline", "noinline"
|
||||
) ++ predefinedFunctions
|
||||
// predefined identifiers that cannot be overridden and do not name a type:
|
||||
val neverValidTypeIdentifiers: Set[String] = Set(
|
||||
"true", "false",
|
||||
) ++ neverIdentifiers
|
||||
// predefined type identifiers:
|
||||
val invalidNewIdentifiers: Set[String] = Set(
|
||||
"byte", "sbyte", "word", "pointer", "void", "long", "bool",
|
||||
"set_carry", "set_zero", "set_overflow", "set_negative",
|
||||
"clear_carry", "clear_zero", "clear_overflow", "clear_negative",
|
||||
"int8", "int16", "int24", "int32", "int40", "int48", "int56", "int64", "int72", "int80", "int88", "int96", "int104", "int112", "int120", "int128",
|
||||
"signed8", "unsigned16") ++ neverValidTypeIdentifiers
|
||||
// built-in special-cased field names; can be considered keywords by some:
|
||||
val invalidFieldNames: Set[String] = Set("addr", "rawaddr", "pointer", "return")
|
||||
}
|
||||
|
@ -486,7 +486,7 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri
|
||||
bank <- bankDeclaration
|
||||
flags <- functionFlags ~ HWS
|
||||
returnType <- identifier ~ SWS
|
||||
if !InvalidReturnTypes(returnType)
|
||||
if !Environment.neverValidTypeIdentifiers(returnType)
|
||||
name <- identifier ~ HWS
|
||||
params <- "(" ~/ AWS ~/ (if (flags("asm")) asmParamDefinition else paramDefinition).rep(sep = AWS ~ "," ~/ AWS) ~ AWS ~ ")" ~/ AWS
|
||||
alignment <- alignmentDeclaration(fastAlignmentForFunctions).? ~/ AWS
|
||||
@ -735,5 +735,4 @@ object MfParser {
|
||||
|
||||
val functionFlags: P[Set[String]] = flags_("asm", "inline", "interrupt", "macro", "noinline", "reentrant", "kernal_interrupt")
|
||||
|
||||
val InvalidReturnTypes: Set[String] = Set("enum", "alias", "array", "const", "stack", "register", "static", "volatile", "import", "struct", "union")
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user