1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-05-31 18:41:30 +00:00

Short syntax for small functions

This commit is contained in:
Karol Stasiak 2019-04-15 19:56:14 +02:00
parent 029e84b0f0
commit d0f64f2cee
5 changed files with 16 additions and 5 deletions

View File

@ -24,6 +24,8 @@
* Aliases now also support subfields.
* Short functions can be now defined using expression syntax.
* 6502: Fixed optimizations using index registers.
* Fixed volatile-related bugs.

View File

@ -6,6 +6,8 @@ Syntax:
`[segment (<segment>)] [<modifiers>] <return_type> <name> ( <params> ) [align ( <alignment> )] [@ <address>] { <body> }`
`[segment (<segment>)] [<modifiers>] <return_type> <name> ( <params> ) [align ( <alignment> )] [@ <address>] = <expression>`
`[segment (<segment>)] asm <return_type> <name> ( <params> ) @ <address> extern`
* `<segment>`: segment name; if absent, then defaults to `default_code_segment` as defined for the platform (usually `default`)
@ -53,3 +55,5 @@ Such functions should be marked as written in assembly and should have their par
* `<body>` is a newline-separated list of either Millfork or assembly statements
* `<expression>` is an expression. It is equivalent to a function body of form `{ return <expression> }`.

View File

@ -372,6 +372,13 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri
def statements: P[List[Statement]] = ("{" ~/ AWS ~ statement.rep(sep = NoCut(EOL) ~ !"}" ~/ Pass) ~/ AWS ~/ "}" ~/ Pass).map(_.flatten.toList)
def mfFunctionSmallBody: P[List[Statement]] = for {
_ <- "=" ~/ AWS
expression <- mfExpression(nonStatementLevel, false)
} yield List(ReturnStatement(Some(expression)).pos(expression.position))
def mfFunctionBody: P[List[Statement]] = statements | mfFunctionSmallBody
def executableStatements: P[Seq[ExecutableStatement]] = ("{" ~/ AWS ~/ executableStatement.rep(sep = NoCut(EOL) ~ !"}" ~/ Pass) ~/ AWS ~ "}").map(_.flatten)
val dispatchLabel: P[ReturnDispatchLabel] =
@ -449,7 +456,7 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri
params <- "(" ~/ AWS ~/ (if (flags("asm")) asmParamDefinition else paramDefinition).rep(sep = AWS ~ "," ~/ AWS) ~ AWS ~ ")" ~/ AWS
alignment <- alignmentDeclaration(fastAlignmentForFunctions).? ~/ AWS
addr <- ("@" ~/ HWS ~/ mfExpression(1, false)).?.opaque("<address>") ~/ AWS
statements <- (externFunctionBody | (if (flags("asm")) asmStatements else statements).map(l => Some(l))) ~/ Pass
statements <- (externFunctionBody | (if (flags("asm")) asmStatements else mfFunctionBody).map(l => Some(l))) ~/ Pass
} yield {
if (flags("interrupt") && flags("macro")) log.error(s"Interrupt function `$name` cannot be macros", Some(p))
if (flags("kernal_interrupt") && flags("macro")) log.error(s"Kernal interrupt function `$name` cannot be macros", Some(p))

View File

@ -135,9 +135,7 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
| void main () {
| output = f(5)
| }
| byte f(byte x) {
| return ((x & $1E) >> 1) + 3
| }
| byte f(byte x) = ((x & $1E) >> 1) + 3
|
""".stripMargin)(_.readByte(0xc000) should equal(5))
}

View File

@ -51,7 +51,7 @@ class DerefSuite extends FunSuite with Matchers {
| ¥(q) = ¥(p) + ¥(q)
| }
|
| noinline pointer id(pointer x) { return x }
| noinline pointer id(pointer x) = x
""".stripMargin){m =>
m.readByte(0xc000) should equal (3)
m.readByte(0xc001) should equal (6)