null assignment operator added

This commit is contained in:
sergeych committed 2026-01-06 11:39:23 +01:00
1 parent 8cd980514b
commit 555c9b94de
11 files changed
+169 -9

No files matched your search

@@ -175,6 +175,7 @@ class Compiler(
// A standalone newline not immediately following a comment resets doc buffer
if (!prevWasComment) clearPendingDoc() else prevWasComment = false
}
else -> {}
}
cc.next()
continue
@@ -3602,6 +3603,9 @@ class Compiler(
Operator(Token.Type.PERCENTASSIGN, lastPriority) { pos, a, b ->
AssignOpRef(BinOp.PERCENT, a, b, pos)
},
Operator(Token.Type.IFNULLASSIGN, lastPriority) { pos, a, b ->
AssignIfNullRef(a, b, pos)
},
// logical 1
Operator(Token.Type.OR, ++lastPriority) { _, a, b ->
foldBinary(BinOp.OR, a, b)?.let { return@Operator ConstRef(it.asReadonly) }
@@ -325,6 +325,7 @@ private class Parser(fromPos: Pos) {
'?' -> {
when (currentChar) {
'=' -> { pos.advance(); Token("?=", from, Token.Type.IFNULLASSIGN) }
':' -> { pos.advance(); Token("?:", from, Token.Type.ELVIS) }
'?' -> { pos.advance(); Token("??", from, Token.Type.ELVIS) }
'.' -> { pos.advance(); Token("?.", from, Token.Type.NULL_COALESCE) }
@@ -34,7 +34,7 @@ data class Token(val value: String, val pos: Pos, val type: Type) {
LPAREN, RPAREN, LBRACE, RBRACE, LBRACKET, RBRACKET, COMMA,
SEMICOLON, COLON,
PLUS, MINUS, STAR, SLASH, PERCENT,
ASSIGN, PLUSASSIGN, MINUSASSIGN, STARASSIGN, SLASHASSIGN, PERCENTASSIGN,
ASSIGN, PLUSASSIGN, MINUSASSIGN, STARASSIGN, SLASHASSIGN, PERCENTASSIGN, IFNULLASSIGN,
PLUS2, MINUS2,
IN, NOTIN, IS, NOTIS, BY,
EQ, NEQ, LT, LTE, GT, GTE, REF_EQ, REF_NEQ, MATCH, NOTMATCH,
@@ -82,7 +82,7 @@ private fun kindOf(type: Type, value: String): HighlightKind? = when (type) {
// operators and symbolic constructs
Type.PLUS, Type.MINUS, Type.STAR, Type.SLASH, Type.PERCENT,
Type.ASSIGN, Type.PLUSASSIGN, Type.MINUSASSIGN, Type.STARASSIGN, Type.SLASHASSIGN, Type.PERCENTASSIGN,
Type.ASSIGN, Type.PLUSASSIGN, Type.MINUSASSIGN, Type.STARASSIGN, Type.SLASHASSIGN, Type.PERCENTASSIGN, Type.IFNULLASSIGN,
Type.PLUS2, Type.MINUS2,
Type.EQ, Type.NEQ, Type.LT, Type.LTE, Type.GT, Type.GTE, Type.REF_EQ, Type.REF_NEQ, Type.MATCH, Type.NOTMATCH,
Type.DOT, Type.ARROW, Type.EQARROW, Type.QUESTION, Type.COLONCOLON,
@@ -1805,6 +1805,21 @@ class RangeRef(
}
}
/** Assignment if null op: target ?= value */
class AssignIfNullRef(
private val target: ObjRef,
private val value: ObjRef,
private val atPos: Pos,
) : ObjRef {
override suspend fun get(scope: Scope): ObjRecord {
val current = target.evalValue(scope)
if (current != ObjNull) return current.asReadonly
val newValue = value.evalValue(scope)
target.setAt(atPos, scope, newValue)
return newValue.asReadonly
}
}
/** Simple assignment: target = value */
class AssignRef(
private val target: ObjRef,