mirror of
https://github.com/irmen/prog8.git
synced 2024-11-18 19:12:44 +00:00
sub decl checking
This commit is contained in:
parent
cba9e7670e
commit
b72bd805e1
@ -63,11 +63,11 @@ statement :
|
||||
| branch_stmt
|
||||
| subroutine
|
||||
| inlineasm
|
||||
| labeldef
|
||||
| returnstmt
|
||||
| forloop
|
||||
| breakstmt
|
||||
| continuestmt
|
||||
| labeldef
|
||||
// @todo whileloop, repeatloop
|
||||
;
|
||||
|
||||
|
@ -17,12 +17,13 @@
|
||||
word plotx
|
||||
byte ploty
|
||||
|
||||
_vm_write_str("Calculating Mandelbrot fractal, have patience...\n")
|
||||
_vm_gfx_clearscr(11)
|
||||
|
||||
for pixely in 0 to height { ; @todo 255 as upper limit doesn't work it overflows the loop
|
||||
for pixelx in 0 to width {
|
||||
xx=flt(pixelx)/width/3+0.2 ; @todo fix division to return float always, add // integer division
|
||||
yy=flt(pixely)/height/3.6+0.4
|
||||
xx=pixelx/width/3+0.2
|
||||
yy=pixely/height/3.6+0.4
|
||||
|
||||
x=0.0
|
||||
y=0.0
|
||||
|
@ -6,33 +6,51 @@
|
||||
|
||||
sub start() -> () {
|
||||
|
||||
const word width = 159
|
||||
const word height = 127
|
||||
word pixelx
|
||||
byte pixely
|
||||
float xx
|
||||
float yy
|
||||
float x = 4999.999
|
||||
float y
|
||||
float x2
|
||||
byte iter
|
||||
word plotx = 40000
|
||||
byte ploty
|
||||
if(X) goto yesx
|
||||
else goto nox
|
||||
|
||||
;yy = pixelx/width/3+0.2 ; @todo fix division to return float always, add // integer division
|
||||
;xx = flt(pixelx)/width/3+0.2 ; @todo fix division to return float always, add // integer division
|
||||
|
||||
_vm_write_num(plotx)
|
||||
_vm_write_char($8d)
|
||||
plotx //= 3 ; @todo fix division to return float always, add // integer division
|
||||
_vm_write_num(plotx)
|
||||
_vm_write_char($8d)
|
||||
yesx:
|
||||
|
||||
x2 = x/33.33 ; @todo fix division to return float always, add // integer division
|
||||
_vm_write_num(x2)
|
||||
_vm_write_char($8d)
|
||||
x2 = x//33.33 ; @todo fix division to return float always, add // integer division
|
||||
_vm_write_num(x2)
|
||||
_vm_write_char($8d)
|
||||
if(X) {
|
||||
A=0
|
||||
goto yesx ;; @todo fix undefined symbol error
|
||||
return
|
||||
} else {
|
||||
A=1
|
||||
goto nox
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
sub bla() -> () {
|
||||
return
|
||||
sub fooz() -> () {
|
||||
return
|
||||
}
|
||||
|
||||
sub fooz2() -> () {
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
A=45
|
||||
|
||||
nox:
|
||||
word i
|
||||
|
||||
for i in 10 to 20 {
|
||||
if(i>12) goto fout ;; @todo fix undefined symbol error
|
||||
break
|
||||
continue
|
||||
|
||||
|
||||
bla() ;; @todo fix undefined symbol error
|
||||
}
|
||||
|
||||
fout:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,10 @@ import kotlin.system.exitProcess
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println("\nProg8 compiler by Irmen de Jong (irmen@razorvine.net)")
|
||||
println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
|
||||
// @todo software license string
|
||||
// println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
|
||||
println("**** This is a prerelease version. Please do not distribute! ****\n")
|
||||
|
||||
if(args.size != 1) {
|
||||
System.err.println("requires one argument: name of module file")
|
||||
exitProcess(1)
|
||||
|
@ -139,10 +139,19 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
||||
checkResult.add(SyntaxError("block memory address must be valid integer 0..\$ffff", block.position))
|
||||
}
|
||||
|
||||
checkSubroutinesPrecededByReturnOrJump(block.statements)
|
||||
checkSubroutinesPrecededByReturnOrJumpAndFollowedByLabelOrSub(block.statements)
|
||||
return super.process(block)
|
||||
}
|
||||
|
||||
override fun process(label: Label): IStatement {
|
||||
// scope check
|
||||
if(label.parent !is Block && label.parent !is Subroutine) {
|
||||
checkResult.add(SyntaxError("Labels can only be defined in the scope of a block or within another subroutine", label.position))
|
||||
}
|
||||
return super.process(label)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check subroutine definition
|
||||
*/
|
||||
@ -166,7 +175,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
||||
err("return registers should be unique")
|
||||
|
||||
super.process(subroutine)
|
||||
checkSubroutinesPrecededByReturnOrJump(subroutine.statements)
|
||||
checkSubroutinesPrecededByReturnOrJumpAndFollowedByLabelOrSub(subroutine.statements)
|
||||
|
||||
// subroutine must contain at least one 'return' or 'goto'
|
||||
// (or if it has an asm block, that must contain a 'rts' or 'jmp')
|
||||
@ -184,12 +193,24 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
||||
}
|
||||
}
|
||||
|
||||
// scope check
|
||||
if(subroutine.parent !is Block && subroutine.parent !is Subroutine) {
|
||||
err("subroutines can only be defined in the scope of a block or within another subroutine")
|
||||
}
|
||||
|
||||
return subroutine
|
||||
}
|
||||
|
||||
private fun checkSubroutinesPrecededByReturnOrJump(statements: MutableList<IStatement>) {
|
||||
private fun checkSubroutinesPrecededByReturnOrJumpAndFollowedByLabelOrSub(statements: MutableList<IStatement>) {
|
||||
// @todo hmm, or move all the subroutines at the end of the block? (no fall-through execution)
|
||||
var preceding: IStatement = BuiltinFunctionStatementPlaceholder
|
||||
var checkNext = false
|
||||
for (stmt in statements) {
|
||||
if(checkNext) {
|
||||
if(stmt !is Label && stmt !is Subroutine)
|
||||
checkResult.add(SyntaxError("preceding subroutine definition at line ${preceding.position.line} should be followed here by a label, another subroutine statement, or nothing", stmt.position))
|
||||
return
|
||||
}
|
||||
if(stmt is Subroutine) {
|
||||
if(preceding !is Return
|
||||
&& preceding !is Jump
|
||||
@ -198,6 +219,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
||||
&& preceding !is BuiltinFunctionStatementPlaceholder) {
|
||||
checkResult.add(SyntaxError("subroutine definition should be preceded by a return, jump, vardecl, or another subroutine statement", stmt.position))
|
||||
}
|
||||
checkNext=true
|
||||
}
|
||||
preceding = stmt
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ class Compiler(private val options: CompilationOptions) {
|
||||
|
||||
class VarGatherer(private val stackvmProg: StackVmProgram): IAstProcessor {
|
||||
// collect all the VarDecls to make them into one global list
|
||||
// @todo maybe keep the block structure intact and allocate them per block? this is needed eventually for the actual 6502 code generation so...
|
||||
override fun process(decl: VarDecl): IStatement {
|
||||
if(decl.type == VarDeclType.MEMORY)
|
||||
TODO("stackVm doesn't support memory vars for now")
|
||||
|
@ -367,9 +367,6 @@ public class prog8Parser extends Parser {
|
||||
public InlineasmContext inlineasm() {
|
||||
return getRuleContext(InlineasmContext.class,0);
|
||||
}
|
||||
public LabeldefContext labeldef() {
|
||||
return getRuleContext(LabeldefContext.class,0);
|
||||
}
|
||||
public ReturnstmtContext returnstmt() {
|
||||
return getRuleContext(ReturnstmtContext.class,0);
|
||||
}
|
||||
@ -382,6 +379,9 @@ public class prog8Parser extends Parser {
|
||||
public ContinuestmtContext continuestmt() {
|
||||
return getRuleContext(ContinuestmtContext.class,0);
|
||||
}
|
||||
public LabeldefContext labeldef() {
|
||||
return getRuleContext(LabeldefContext.class,0);
|
||||
}
|
||||
public StatementContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@ -497,35 +497,35 @@ public class prog8Parser extends Parser {
|
||||
enterOuterAlt(_localctx, 15);
|
||||
{
|
||||
setState(133);
|
||||
labeldef();
|
||||
returnstmt();
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
enterOuterAlt(_localctx, 16);
|
||||
{
|
||||
setState(134);
|
||||
returnstmt();
|
||||
forloop();
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
enterOuterAlt(_localctx, 17);
|
||||
{
|
||||
setState(135);
|
||||
forloop();
|
||||
breakstmt();
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
enterOuterAlt(_localctx, 18);
|
||||
{
|
||||
setState(136);
|
||||
breakstmt();
|
||||
continuestmt();
|
||||
}
|
||||
break;
|
||||
case 19:
|
||||
enterOuterAlt(_localctx, 19);
|
||||
{
|
||||
setState(137);
|
||||
continuestmt();
|
||||
labeldef();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3496,9 +3496,9 @@ public class prog8Parser extends Parser {
|
||||
"\2\2y\u008d\5\16\b\2z\u008d\5\24\13\2{\u008d\5\22\n\2|\u008d\5\26\f\2"+
|
||||
"}\u008d\5\30\r\2~\u008d\5\36\20\2\177\u008d\5 \21\2\u0080\u008d\5\f\7"+
|
||||
"\2\u0081\u008d\5$\23\2\u0082\u008d\5*\26\2\u0083\u008d\5Z.\2\u0084\u008d"+
|
||||
"\5^\60\2\u0085\u008d\5L\'\2\u0086\u008d\5J&\2\u0087\u008d\5\n\6\2\u0088"+
|
||||
"\u008d\5.\30\2\u0089\u008d\5b\62\2\u008a\u008d\5\60\31\2\u008b\u008d\5"+
|
||||
"\62\32\2\u008cy\3\2\2\2\u008cz\3\2\2\2\u008c{\3\2\2\2\u008c|\3\2\2\2\u008c"+
|
||||
"\5^\60\2\u0085\u008d\5L\'\2\u0086\u008d\5J&\2\u0087\u008d\5.\30\2\u0088"+
|
||||
"\u008d\5b\62\2\u0089\u008d\5\60\31\2\u008a\u008d\5\62\32\2\u008b\u008d"+
|
||||
"\5\n\6\2\u008cy\3\2\2\2\u008cz\3\2\2\2\u008c{\3\2\2\2\u008c|\3\2\2\2\u008c"+
|
||||
"}\3\2\2\2\u008c~\3\2\2\2\u008c\177\3\2\2\2\u008c\u0080\3\2\2\2\u008c\u0081"+
|
||||
"\3\2\2\2\u008c\u0082\3\2\2\2\u008c\u0083\3\2\2\2\u008c\u0084\3\2\2\2\u008c"+
|
||||
"\u0085\3\2\2\2\u008c\u0086\3\2\2\2\u008c\u0087\3\2\2\2\u008c\u0088\3\2"+
|
||||
|
@ -1464,7 +1464,10 @@ class StackVm(val traceOutputFile: String?) {
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println("\nProg8 StackVM by Irmen de Jong (irmen@razorvine.net)")
|
||||
println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
|
||||
// @todo software license string
|
||||
// println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
|
||||
println("**** This is a prerelease version. Please do not distribute! ****\n")
|
||||
|
||||
if(args.size != 1) {
|
||||
System.err.println("requires one argument: name of stackvm sourcecode file")
|
||||
exitProcess(1)
|
||||
|
Loading…
Reference in New Issue
Block a user