mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
fix grammar problem: \x and \u escape sequences didn't work in character literals.
This commit is contained in:
parent
900cdd3fa1
commit
81deed143b
@ -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(),
|
||||
|
@ -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)
|
||||
})
|
||||
|
@ -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 }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
@ -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 :
|
||||
|
Loading…
x
Reference in New Issue
Block a user