fix grammar problem: \x and \u escape sequences didn't work in character literals.

This commit is contained in:
Irmen de Jong 2021-12-05 18:11:40 +01:00
parent 900cdd3fa1
commit 81deed143b
6 changed files with 44 additions and 52 deletions

View File

@ -288,8 +288,10 @@ private fun Prog8ANTLRParser.FunctioncallContext.toAst(): FunctionCall {
FunctionCall(location, expression_list().toAst().toMutableList(), toPosition())
}
private fun Prog8ANTLRParser.InlineasmContext.toAst() =
InlineAssembly(INLINEASMBLOCK().text, toPosition())
private fun Prog8ANTLRParser.InlineasmContext.toAst(): InlineAssembly {
val text = INLINEASMBLOCK().text
return InlineAssembly(text.substring(2, text.length-2), toPosition())
}
private fun Prog8ANTLRParser.ReturnstmtContext.toAst() : Return {
return Return(expression()?.toAst(), toPosition())
@ -356,8 +358,7 @@ private fun Prog8ANTLRParser.DirectiveargContext.toAst() : DirectiveArg {
val str = stringliteral()
if(str?.ALT_STRING_ENCODING() != null)
throw SyntaxError("can't use alternate string s for directive arguments", toPosition())
return DirectiveArg(stringliteral()?.text, identifier()?.text, integerliteral()?.toAst()?.number?.toUInt(), toPosition())
return DirectiveArg(str?.text?.substring(1, text.length-1), identifier()?.text, integerliteral()?.toAst()?.number?.toUInt(), toPosition())
}
private fun Prog8ANTLRParser.IntegerliteralContext.toAst(): NumericLiteral {
@ -480,11 +481,15 @@ private fun Prog8ANTLRParser.ExpressionContext.toAst() : Expression {
throw FatalAstException(text)
}
private fun Prog8ANTLRParser.CharliteralContext.toAst(): CharLiteral =
CharLiteral(unescape(this.SINGLECHAR().text, toPosition())[0], this.ALT_STRING_ENCODING() != null, toPosition())
private fun Prog8ANTLRParser.CharliteralContext.toAst(): CharLiteral {
val text = this.SINGLECHAR().text
return CharLiteral(unescape(text.substring(1, text.length-1), toPosition())[0], this.ALT_STRING_ENCODING() != null, toPosition())
}
private fun Prog8ANTLRParser.StringliteralContext.toAst(): StringLiteralValue =
StringLiteralValue(unescape(this.STRING().text, toPosition()), ALT_STRING_ENCODING()!=null, toPosition())
private fun Prog8ANTLRParser.StringliteralContext.toAst(): StringLiteralValue {
val text=this.STRING().text
return StringLiteralValue(unescape(text.substring(1, text.length-1), toPosition()), ALT_STRING_ENCODING() != null, toPosition())
}
private fun Prog8ANTLRParser.ArrayindexedContext.toAst(): ArrayIndexedExpression {
return ArrayIndexedExpression(scoped_identifier().toAst(),

View File

@ -2,6 +2,7 @@ package prog8.ast.antlr
import prog8.ast.base.Position
import prog8.ast.base.SyntaxError
import kotlin.NumberFormatException
fun escape(str: String): String {
val es = str.map {
@ -32,12 +33,24 @@ fun unescape(str: String, position: Position): String {
'"' -> '"'
'\'' -> '\''
'u' -> {
"${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}".toInt(16).toChar()
try {
"${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}".toInt(16).toChar()
} catch (sb: StringIndexOutOfBoundsException) {
throw SyntaxError("invalid \\u escape sequence", position)
} catch (nf: NumberFormatException) {
throw SyntaxError("invalid \\u escape sequence", position)
}
}
'x' -> {
// special hack 0x8000..0x80ff will be outputted verbatim without encoding
val hex = ("" + iter.nextChar() + iter.nextChar()).toInt(16)
(0x8000 + hex).toChar()
try {
val hex = ("" + iter.nextChar() + iter.nextChar()).toInt(16)
(0x8000 + hex).toChar()
} catch (sb: StringIndexOutOfBoundsException) {
throw SyntaxError("invalid \\x escape sequence", position)
} catch (nf: NumberFormatException) {
throw SyntaxError("invalid \\x escape sequence", position)
}
}
else -> throw SyntaxError("invalid escape char in string: \\$ec", position)
})

View File

@ -706,6 +706,7 @@ class Subroutine(override val name: String,
return KeepAresult(false, saveAonReturn)
}
// TODO fix this to also look in asm nodes in subscopes
fun amountOfRtsInAsm(): Int = statements
.asSequence()
.filter { it is InlineAssembly }

View File

@ -3,7 +3,10 @@ TODO
For next compiler release (7.5)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
fix: cx16.r0 isn't seen as zeropage so @(cx16.r0) still copies it to temp zp
fix: when statements generate unneeded branches to choice_end?
fix: amountOfRtsInAsm() look in subscopes too
Blocked by an official Commander-x16 v39 release

View File

@ -4,28 +4,13 @@
main {
sub start() {
ubyte num_banks = cx16.numbanks()
txt.print("number of ram banks ")
txt.print_ub(num_banks)
txt.print(" = ")
txt.print_uw($0008*num_banks)
txt.print("kb\n")
print_banks()
cx16.rambank(55)
cx16.rombank(3)
print_banks()
}
sub print_banks() {
ubyte rambank = cx16.getrambank()
ubyte rombank = cx16.getrombank()
cx16.rombank(0) ; enable kernal
txt.print("ram bank ")
txt.print_ub(rambank)
txt.nl()
txt.print("rom bank ")
txt.print_ub(rombank)
txt.nl()
cx16.rombank(rombank)
str text = "hello"
txt.print(text)
txt.print("hello2\u0032")
ubyte chr1 = '\x33'
txt.chrout(chr1)
%asm {{
nop
}}
}
}

View File

@ -33,31 +33,16 @@ ALT_STRING_ENCODING: '@';
FLOAT_NUMBER : FNUMBER (('E'|'e') ('+' | '-')? FNUMBER)? ; // sign comes later from unary expression
fragment FNUMBER : ('0' .. '9') + ('.' ('0' .. '9') +)? ;
fragment STRING_ESCAPE_SEQ : '\\' . | '\\' EOL;
fragment STRING_ESCAPE_SEQ : '\\' . | '\\x' . . | '\\u' . . . .;
STRING :
'"' ( STRING_ESCAPE_SEQ | ~[\\\r\n\f"] )* '"'
{
// get rid of the enclosing quotes
String s = getText();
setText(s.substring(1, s.length() - 1));
}
;
INLINEASMBLOCK :
'{{' .+? '}}'
{
// get rid of the enclosing double braces
String s = getText();
setText(s.substring(2, s.length() - 2));
}
;
SINGLECHAR :
'\'' ( STRING_ESCAPE_SEQ | ~[\\\r\n\f"] ) '\''
{
// get rid of the enclosing quotes
String s = getText();
setText(s.substring(1, s.length() - 1));
}
'\'' ( STRING_ESCAPE_SEQ | ~[\\\r\n\f'] ) '\''
;
ZEROPAGE :