Skip to content

Commit ef1c665

Browse files
committed
allow underscores for numerical grouping
1 parent d56565b commit ef1c665

File tree

5 files changed

+45
-34
lines changed

5 files changed

+45
-34
lines changed

compiler/test/ast/TestProg8Parser.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,4 +1025,25 @@ main {
10251025
compileText(VMTarget(), false, src, writeAssembly = false) shouldNotBe null
10261026
}
10271027

1028+
test("underscores for numeric groupings") {
1029+
val src="""
1030+
%option enable_floats
1031+
main {
1032+
sub start() {
1033+
uword w1 = 000_1234_5__
1034+
uword w2 = ${'$'}ff_ee
1035+
uword w3 = %11_0000_111111__0000
1036+
float fl = 3_000_001.141_592_654
1037+
}
1038+
}"""
1039+
val result = compileText(VMTarget(), false, src, writeAssembly = false)!!
1040+
val st = result.compilerAst.entrypoint.statements
1041+
st.size shouldBe 8
1042+
val assigns = st.filterIsInstance<Assignment>()
1043+
(assigns[0].value as NumericLiteral).number shouldBe 12345
1044+
(assigns[1].value as NumericLiteral).number shouldBe 0xffee
1045+
(assigns[2].value as NumericLiteral).number shouldBe 0b1100001111110000
1046+
(assigns[3].value as NumericLiteral).number shouldBe 3000001.141592654
1047+
}
1048+
10281049
})

compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -371,13 +371,14 @@ private fun DirectiveargContext.toAst() : DirectiveArg {
371371
}
372372

373373
private fun IntegerliteralContext.toAst(): NumericLiteralNode {
374-
fun makeLiteral(text: String, radix: Int): NumericLiteralNode {
374+
fun makeLiteral(literalTextWithGrouping: String, radix: Int): NumericLiteralNode {
375+
val literalText = literalTextWithGrouping.replace("_", "")
375376
val integer: Int
376377
var datatype = DataType.UBYTE
377378
when (radix) {
378379
10 -> {
379380
integer = try {
380-
text.toInt()
381+
literalText.toInt()
381382
} catch(x: NumberFormatException) {
382383
throw SyntaxError("invalid decimal literal ${x.message}", toPosition())
383384
}
@@ -391,19 +392,19 @@ private fun IntegerliteralContext.toAst(): NumericLiteralNode {
391392
}
392393
}
393394
2 -> {
394-
if(text.length>8)
395+
if(literalText.length>8)
395396
datatype = DataType.UWORD
396397
try {
397-
integer = text.toInt(2)
398+
integer = literalText.toInt(2)
398399
} catch(x: NumberFormatException) {
399400
throw SyntaxError("invalid binary literal ${x.message}", toPosition())
400401
}
401402
}
402403
16 -> {
403-
if(text.length>2)
404+
if(literalText.length>2)
404405
datatype = DataType.UWORD
405406
try {
406-
integer = text.toInt(16)
407+
integer = literalText.toInt(16)
407408
} catch(x: NumberFormatException) {
408409
throw SyntaxError("invalid hexadecimal literal ${x.message}", toPosition())
409410
}
@@ -542,7 +543,7 @@ private fun Expression_listContext.toAst() = expression().map{ it.toAst() }
542543
private fun Scoped_identifierContext.toAst() : IdentifierReference =
543544
IdentifierReference(NAME().map { it.text }, toPosition())
544545

545-
private fun FloatliteralContext.toAst() = text.toDouble()
546+
private fun FloatliteralContext.toAst() = text.replace("_","").toDouble()
546547

547548
private fun BooleanliteralContext.toAst() = when(text) {
548549
"true" -> true

docs/source/todo.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
TODO
33
====
44

5+
- document underscores in numeric literals for grouping
6+
57
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
68

79
...
@@ -78,7 +80,6 @@ What if we were to re-introduce Structs in prog8? Some thoughts:
7880
Other language/syntax features to think about
7981
---------------------------------------------
8082

81-
- underscores in numeric literals for grouping
8283
- chained comparisons `10<x<20` , `x==y==z` (desugars to `10<x and x<20`, `x==y and y==z`) BUT this changes the semantics of what it is right now ! (x==(y==z) 0> x==true)
8384
- postincrdecr as expression, preincrdecr expression (`y = x++`, `y = ++x`) .... is this even possible, expression with side effects like this?
8485
- negative array index to refer to an element from the end of the array. Python `[-1]` or Raku syntax `[\*-1]` , `[\*/2]` .... \*=size of the array

examples/test.p8

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,9 @@
1-
%import textio
2-
%zeropage basicsafe
3-
1+
%option enable_floats
42
main {
5-
const ubyte VAL = 11
63
sub start() {
7-
uword w
8-
9-
for w in 0 to 20 {
10-
ubyte x,y,z=13
11-
12-
txt.print_ub(x)
13-
txt.spc()
14-
txt.print_ub(y)
15-
txt.spc()
16-
txt.print_ub(z)
17-
txt.spc()
18-
txt.print_uw(w)
19-
txt.nl()
20-
x++
21-
y++
22-
z++
23-
}
4+
uword w1 = 000_1234_5__
5+
uword w2 = $ff_ee
6+
uword w3 = %11_0000_111111__0000
7+
float fl = 3_000_001.141_592_654
248
}
259
}

parser/antlr/Prog8ANTLR.g4

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@ WS : [ \t] -> skip ;
2525
// WS2 : '\\' EOL -> skip;
2626
VOID: 'void';
2727
NAME : [\p{Letter}][\p{Letter}\p{Mark}\p{Digit}_]* ; // match unicode properties
28-
DEC_INTEGER : ('0'..'9') | (('1'..'9')('0'..'9')+);
29-
HEX_INTEGER : '$' (('a'..'f') | ('A'..'F') | ('0'..'9'))+ ;
30-
BIN_INTEGER : '%' ('0' | '1')+ ;
28+
DEC_INTEGER : DEC_DIGIT (DEC_DIGIT | '_')* ;
29+
HEX_INTEGER : '$' HEX_DIGIT (HEX_DIGIT | '_')* ;
30+
BIN_INTEGER : '%' BIN_DIGIT (BIN_DIGIT | '_')* ;
3131
ADDRESS_OF: '&' ;
3232
INVALID_AND_COMPOSITE: '&&' ;
3333

34+
fragment HEX_DIGIT: ('a'..'f') | ('A'..'F') | ('0'..'9') ;
35+
fragment BIN_DIGIT: ('0' | '1') ;
36+
fragment DEC_DIGIT: ('0'..'9') ;
37+
3438
FLOAT_NUMBER : FNUMBER (('E'|'e') ('+' | '-')? DEC_INTEGER)? ; // sign comes later from unary expression
3539
FNUMBER : FDOTNUMBER | FNUMDOTNUMBER ;
36-
FDOTNUMBER : '.' ('0'..'9')+ ;
37-
FNUMDOTNUMBER : ('0'..'9')+ ('.' ('0'..'9')+ )? ;
40+
FDOTNUMBER : '.' (DEC_DIGIT | '_')+ ;
41+
FNUMDOTNUMBER : DEC_DIGIT (DEC_DIGIT | '_')* FDOTNUMBER? ;
3842

3943
STRING_ESCAPE_SEQ : '\\' . | '\\x' . . | '\\u' . . . .;
4044
STRING :

0 commit comments

Comments
 (0)