mirror of
https://github.com/irmen/prog8.git
synced 2025-02-03 11:32:41 +00:00
antlr grammar now understands underscores in identifier names
This commit is contained in:
parent
3e34a3ef72
commit
788f6b44a6
@ -52,6 +52,8 @@ internal class AstChecker(private val program: Program,
|
||||
|
||||
override fun visit(module: Module) {
|
||||
super.visit(module)
|
||||
if(module.name.startsWith('_'))
|
||||
errors.err("module names cannot start with an underscore", module.position)
|
||||
val directives = module.statements.filterIsInstance<Directive>().groupBy { it.directive }
|
||||
directives.filter { it.value.size > 1 }.forEach{ entry ->
|
||||
when(entry.key) {
|
||||
@ -62,6 +64,10 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(identifier: IdentifierReference) {
|
||||
if(identifier.nameInSource.any { it.startsWith('_') }) {
|
||||
errors.err("identifiers cannot start with an underscore", identifier.position)
|
||||
}
|
||||
|
||||
checkLongType(identifier)
|
||||
val stmt = identifier.targetStatement(program)
|
||||
if(stmt==null)
|
||||
@ -266,6 +272,9 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(block: Block) {
|
||||
if(block.name.startsWith('_'))
|
||||
errors.err("block names cannot start with an underscore", block.position)
|
||||
|
||||
val addr = block.address
|
||||
if(addr!=null && addr>65535u) {
|
||||
errors.err("block memory address must be valid integer 0..\$ffff", block.position)
|
||||
@ -295,6 +304,9 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(label: Label) {
|
||||
if(label.name.startsWith('_'))
|
||||
errors.err("labels cannot start with an underscore", label.position)
|
||||
|
||||
// scope check
|
||||
if(label.parent !is Block && label.parent !is Subroutine && label.parent !is AnonymousScope) {
|
||||
errors.err("Labels can only be defined in the scope of a block, a loop body, or within another subroutine", label.position)
|
||||
@ -336,6 +348,9 @@ internal class AstChecker(private val program: Program,
|
||||
override fun visit(subroutine: Subroutine) {
|
||||
fun err(msg: String) = errors.err(msg, subroutine.position)
|
||||
|
||||
if(subroutine.name.startsWith('_'))
|
||||
errors.err("subroutine names cannot start with an underscore", subroutine.position)
|
||||
|
||||
if(subroutine.name in BuiltinFunctions)
|
||||
err("cannot redefine a built-in function")
|
||||
|
||||
@ -474,6 +489,9 @@ internal class AstChecker(private val program: Program,
|
||||
// Non-string and non-ubytearray Pass-by-reference datatypes can not occur as parameters to a subroutine directly
|
||||
// Instead, their reference (address) should be passed (as an UWORD).
|
||||
for(p in subroutine.parameters) {
|
||||
if(p.name.startsWith('_'))
|
||||
errors.err("parameter names cannot start with an underscore", p.position)
|
||||
|
||||
if(p.type in PassByReferenceDatatypes && p.type !in listOf(DataType.STR, DataType.ARRAY_UB)) {
|
||||
errors.err("this pass-by-reference type can't be used as a parameter type. Instead, use an uword to receive the address, or access the variable from the outer scope directly.", p.position)
|
||||
}
|
||||
|
@ -246,7 +246,8 @@ private fun Asmsub_paramsContext.toAst(): List<AsmSubroutineParameter>
|
||||
val identifiers = vardecl.identifier()
|
||||
if(identifiers.size>1)
|
||||
throw SyntaxError("parameter name must be singular", identifiers[0].toPosition())
|
||||
AsmSubroutineParameter(identifiers[0].NAME().text, datatype, registerorpair, statusregister, toPosition())
|
||||
val identifiername = identifiers[0].NAME() ?: identifiers[0].UNDERSCORENAME() ?: identifiers[0].UNDERSCOREPLACEHOLDER()
|
||||
AsmSubroutineParameter(identifiername.text, datatype, registerorpair, statusregister, toPosition())
|
||||
}
|
||||
|
||||
private fun Functioncall_stmtContext.toAst(): Statement {
|
||||
@ -316,7 +317,8 @@ private fun Sub_paramsContext.toAst(): List<SubroutineParameter> =
|
||||
val identifiers = it.identifier()
|
||||
if(identifiers.size>1)
|
||||
throw SyntaxError("parameter name must be singular", identifiers[0].toPosition())
|
||||
SubroutineParameter(identifiers[0].NAME().text, datatype, it.toPosition())
|
||||
val identifiername = identifiers[0].NAME() ?: identifiers[0].UNDERSCORENAME() ?: identifiers[0].UNDERSCOREPLACEHOLDER()
|
||||
SubroutineParameter(identifiername.text, datatype, it.toPosition())
|
||||
}
|
||||
|
||||
private fun Assign_targetContext.toAst() : AssignTarget {
|
||||
@ -556,8 +558,9 @@ private fun StringliteralContext.toAst(): StringLiteral {
|
||||
|
||||
private fun Expression_listContext.toAst() = expression().map{ it.toAst() }
|
||||
|
||||
private fun Scoped_identifierContext.toAst() : IdentifierReference =
|
||||
IdentifierReference(NAME().map { it.text }, toPosition())
|
||||
private fun Scoped_identifierContext.toAst() : IdentifierReference {
|
||||
return IdentifierReference(identifier().map { it.text }, toPosition())
|
||||
}
|
||||
|
||||
private fun FloatliteralContext.toAst() = text.replace("_","").toDouble()
|
||||
|
||||
@ -669,7 +672,8 @@ private fun VardeclContext.toAst(type: VarDeclType, value: Expression?): VarDecl
|
||||
else -> ZeropageWish.DONTCARE
|
||||
}
|
||||
val identifiers = identifier()
|
||||
val name = if(identifiers.size==1) identifiers[0].NAME().text else "<multiple>"
|
||||
val identifiername = identifiers[0].NAME() ?: identifiers[0].UNDERSCORENAME() ?: identifiers[0].UNDERSCOREPLACEHOLDER()
|
||||
val name = if(identifiers.size==1) identifiername.text else "<multiple>"
|
||||
val isArray = ARRAYSIG() != null || arrayindex() != null
|
||||
val split = options.SPLIT().isNotEmpty()
|
||||
val origDt = datatype()?.toAst() ?: DataType.UNDEFINED
|
||||
@ -690,7 +694,10 @@ private fun VardeclContext.toAst(type: VarDeclType, value: Expression?): VarDecl
|
||||
zp,
|
||||
arrayindex()?.toAst(),
|
||||
name,
|
||||
if(identifiers.size==1) emptyList() else identifiers.map { it.NAME().text },
|
||||
if(identifiers.size==1) emptyList() else identifiers.map {
|
||||
val idname = it.NAME() ?: it.UNDERSCORENAME() ?: it.UNDERSCOREPLACEHOLDER()
|
||||
idname.text
|
||||
},
|
||||
value,
|
||||
options.SHARED().isNotEmpty(),
|
||||
split,
|
||||
|
@ -906,12 +906,12 @@ class ArrayLiteral(val type: InferredTypes.InferredType, // inferred because
|
||||
else if(elementType in WordDatatypes && value.all { it is NumericLiteral || it is AddressOf || it is IdentifierReference}) {
|
||||
val castArray = value.map {
|
||||
when(it) {
|
||||
is AddressOf -> it as Expression
|
||||
is IdentifierReference -> it as Expression
|
||||
is AddressOf -> it
|
||||
is IdentifierReference -> it
|
||||
is NumericLiteral -> {
|
||||
val numcast = it.cast(elementType, true)
|
||||
if(numcast.isValid)
|
||||
numcast.valueOrZero() as Expression
|
||||
numcast.valueOrZero()
|
||||
else
|
||||
return null // abort
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ TODO
|
||||
====
|
||||
|
||||
try to replace the variable number of assignment targets by allowing placeholder '_' target
|
||||
or try to do this with 'void' instead, is more prog8-like?
|
||||
|
||||
|
||||
check souce code of examples and library, for void calls that could now be turned into multi-assign calls.
|
||||
|
@ -25,6 +25,8 @@ WS : [ \t] -> skip ;
|
||||
// WS2 : '\\' EOL -> skip;
|
||||
VOID: 'void';
|
||||
NAME : [\p{Letter}][\p{Letter}\p{Mark}\p{Digit}_]* ; // match unicode properties
|
||||
UNDERSCORENAME : '_' NAME ; // match unicode properties
|
||||
UNDERSCOREPLACEHOLDER: '_' ;
|
||||
DEC_INTEGER : DEC_DIGIT (DEC_DIGIT | '_')* ;
|
||||
HEX_INTEGER : '$' HEX_DIGIT (HEX_DIGIT | '_')* ;
|
||||
BIN_INTEGER : '%' BIN_DIGIT (BIN_DIGIT | '_')* ;
|
||||
@ -220,9 +222,9 @@ breakstmt : 'break';
|
||||
|
||||
continuestmt: 'continue';
|
||||
|
||||
identifier : NAME ;
|
||||
identifier : NAME | UNDERSCORENAME | UNDERSCOREPLACEHOLDER;
|
||||
|
||||
scoped_identifier : NAME ('.' NAME)* ;
|
||||
scoped_identifier : identifier ('.' identifier)* ;
|
||||
|
||||
integerliteral : intpart=(DEC_INTEGER | HEX_INTEGER | BIN_INTEGER) ;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user