Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: DATE$ and TIME$ should be funcs, not special vars #87

Merged
merged 1 commit into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ func
| ALLOCARRAY varsuffix LPAREN expr (COMMA expr)? RPAREN # FuncAllocArray
| LTRIMDLR LPAREN str=expr RPAREN # FuncLTrimDlr
| RTRIMDLR LPAREN str=expr RPAREN # FuncRTrimDlr
| DATEDLR # FuncDateDlr
| TIMEDLR # FuncTimeDlr
;

funcname
Expand Down Expand Up @@ -806,6 +808,14 @@ RTRIMDLR
: R T R I M DOLLAR
;

DATEDLR
: D A T E DOLLAR
;

TIMEDLR
: T I M E DOLLAR
;

GOSUB
: G O S U B
;
Expand Down
157 changes: 1 addition & 156 deletions libbababasic/src/main/java/io/atha/libbababasic/domain/STObjects.kt
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,7 @@ enum class PuffinBasicAtomTypeId(protected val _repr: Char?) {
} else if (variable.isUDF) {
STUDF(STStringScalarValue(), variable)
} else if (variable.isScalar) {
val varname = variable.variableName.varname
if (varname.equals("date", ignoreCase = true)) {
STVariable(STStringScalarDateValue(), variable)
} else if (varname.equals("time", ignoreCase = true)) {
STVariable(STStringScalarTimeValue(), variable)
} else {
STVariable(STStringScalarValue(), variable)
}
STVariable(STStringScalarValue(), variable)
} else {
throw InternalError("Variable type not supported: $variable")
}
Expand Down Expand Up @@ -1468,154 +1461,6 @@ private class STStringScalarValue : STValue {
}
}

private class STStringScalarTimeValue : STValue {
private var time: LocalTime? = null
override fun printFormat(): String? {
return string
}

override fun writeFormat(): String? {
return string
}

override fun assign(entry: STValue) {
string = entry.string
}

override var int32: Int
get() {
throw InternalError("Can't cast String to int32")
}
set(value) {
throw InternalError("Can't cast int32 to String")
}
override var int64: Long
get() {
throw InternalError("Can't cast String to int64")
}
set(_) {
throw InternalError("Can't cast int64 to String")
}
override var float32: Float
get() {
throw InternalError("Can't cast String to float32")
}
set(_) {
throw InternalError("Can't cast float32 to String")
}
override var float64: Double
get() {
throw InternalError("Can't cast String to float64")
}
set(_) {
throw InternalError("Can't cast float64 to String")
}
override val roundedInt32: Int
get() {
throw InternalError("Can't cast String to int32")
}
override val roundedInt64: Long
get() {
throw InternalError("Can't cast String to int64")
}
override var string: String?
get() = formatLocalTime((if (time != null) time else LocalTime.now())!!)
set(value) {
time = LocalTime.parse(value, FORMATTER)
}

private fun formatLocalTime(time: LocalTime): String {
return time.format(FORMATTER)
}

override var fieldLength: Int
get() = 0
set(fieldLength) {
throw RuntimeError(
RuntimeError.ErrorCode.ILLEGAL_FUNCTION_PARAM,
"TIME$ cannot be used for setting field length!"
)
}

companion object {
private val FORMATTER = DateTimeFormatter.ISO_LOCAL_TIME
}
}

private class STStringScalarDateValue : STValue {
private var date: LocalDate? = null
override fun printFormat(): String? {
return string
}

override fun writeFormat(): String? {
return string
}

override fun assign(entry: STValue) {
string = entry.string
}

override var int32: Int
get() {
throw InternalError("Can't cast String to int32")
}
set(_) {
throw InternalError("Can't cast int32 to String")
}
override var int64: Long
get() {
throw InternalError("Can't cast String to int64")
}
set(value) {
throw InternalError("Can't cast int64 to String")
}
override var float32: Float
get() {
throw InternalError("Can't cast String to float32")
}
set(value) {
throw InternalError("Can't cast float32 to String")
}
override var float64: Double
get() {
throw InternalError("Can't cast String to float64")
}
set(value) {
throw InternalError("Can't cast float64 to String")
}
override val roundedInt32: Int
get() {
throw InternalError("Can't cast String to int32")
}
override val roundedInt64: Long
get() {
throw InternalError("Can't cast String to int64")
}
override var string: String?
get() = formatLocalDate((if (date != null) date else LocalDate.now())!!)
set(value) {
date = LocalDate.parse(value, FORMATTER)
}

private fun formatLocalDate(date: LocalDate): String {
return date.format(FORMATTER)
}

override var fieldLength: Int
get() = 0
set(fieldLength) {
throw RuntimeError(
RuntimeError.ErrorCode.ILLEGAL_FUNCTION_PARAM,
"DATE$ cannot be used for setting field length!"
)
}

companion object {
private val FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE
}
}

internal class ArrayReferenceValue(private val variable: STLValue) : STValue {
private var index1d = 0
private val value: AbstractSTArrayValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class IR(@JvmField val symbolTable: SymbolTable) {
MOUSEBUTTONPRESSED("mousebuttonpressed"), MOUSEBUTTONRELEASED("mousebuttonreleased"), ISKEYPRESSED(
"iskeypressed"
),
LTRIMDLR("ltrim$"), RTRIMDLR("rtrim$")
LTRIMDLR("ltrim$"), RTRIMDLR("rtrim$"), DATEDLR("date$"), TIMEDLR("date$")
}

class InputRef(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import io.atha.libbababasic.file.BBFile.FileAccessMode
import io.atha.libbababasic.file.BBFile.FileOpenMode
import io.atha.libbababasic.grammar.BabaBASICBaseListener
import io.atha.libbababasic.grammar.BabaBASICParser
import io.atha.libbababasic.grammar.BabaBASICParser.FuncDateDlrContext
import io.atha.libbababasic.grammar.BabaBASICParser.FuncTimeDlrContext
import io.atha.libbababasic.grammar.BabaBASICParser.AccessContext
import io.atha.libbababasic.grammar.BabaBASICParser.Array1dcopystmtContext
import io.atha.libbababasic.grammar.BabaBASICParser.Array1dsortstmtContext
Expand Down Expand Up @@ -1130,6 +1132,24 @@ class IRListener(
)
}

override fun exitFuncDateDlr(ctx: FuncDateDlrContext) {
nodeToInstruction.put(
ctx, ir.addInstruction(
sourceFile, currentLineNumber, ctx.start.startIndex, ctx.stop.stopIndex,
OpCode.DATEDLR, SymbolTable.NULL_ID, SymbolTable.NULL_ID,
ir.symbolTable.addTmp(PuffinBasicAtomTypeId.STRING) { _: STEntry? -> })
)
}

override fun exitFuncTimeDlr(ctx: FuncTimeDlrContext) {
nodeToInstruction.put(
ctx, ir.addInstruction(
sourceFile, currentLineNumber, ctx.start.startIndex, ctx.stop.stopIndex,
OpCode.TIMEDLR, SymbolTable.NULL_ID, SymbolTable.NULL_ID,
ir.symbolTable.addTmp(PuffinBasicAtomTypeId.STRING) { _: STEntry? -> })
)
}

override fun exitFuncMkiDlr(ctx: FuncMkiDlrContext) {
nodeToInstruction.put(
ctx, addFuncWithExprInstruction(OpCode.MKIDLR, ctx, ctx.expr(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import io.atha.libbababasic.runtime.Functions.cvd
import io.atha.libbababasic.runtime.Functions.cvi
import io.atha.libbababasic.runtime.Functions.cvl
import io.atha.libbababasic.runtime.Functions.cvs
import io.atha.libbababasic.runtime.Functions.datedlr
import io.atha.libbababasic.runtime.Functions.e
import io.atha.libbababasic.runtime.Functions.environdlr
import io.atha.libbababasic.runtime.Functions.eof
Expand Down Expand Up @@ -89,6 +90,7 @@ import io.atha.libbababasic.runtime.Functions.strdlr
import io.atha.libbababasic.runtime.Functions.stringdlr
import io.atha.libbababasic.runtime.Functions.tan
import io.atha.libbababasic.runtime.Functions.tanh
import io.atha.libbababasic.runtime.Functions.timedlr
import io.atha.libbababasic.runtime.Functions.timer
import io.atha.libbababasic.runtime.Functions.timerMillis
import io.atha.libbababasic.runtime.Functions.toDeg
Expand Down Expand Up @@ -287,6 +289,8 @@ class BBRuntime(
private fun runInstruction(instruction: IR.Instruction): Boolean {
var nextProgramCounter = programCounter + 1
when (instruction.opCode) {
OpCode.TIMEDLR -> timedlr(ir.symbolTable, instruction)
OpCode.DATEDLR -> datedlr(ir.symbolTable, instruction)
OpCode.VARREF -> varref(ir.symbolTable, instruction)
OpCode.DIM -> {
if (params!!.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import java.nio.charset.StandardCharsets
import java.time.Duration
import java.time.Instant
import java.time.ZonedDateTime
import java.util.Date
import java.util.Random
import java.util.concurrent.TimeUnit
import kotlin.math.abs
Expand All @@ -22,6 +23,20 @@ import kotlin.math.roundToLong
import kotlin.math.sqrt

object Functions {
@JvmStatic
fun timedlr(symbolTable: SymbolTable, instruction: IR.Instruction) {
val result = symbolTable[instruction.result]!!.value
val now = Date()
result!!.string = String.format("%1\$tT.%1\$tL000", now)
}

@JvmStatic
fun datedlr(symbolTable: SymbolTable, instruction: IR.Instruction) {
val result = symbolTable[instruction.result]!!.value
val now = Date()
result!!.string = String.format("%1\$tm-%1\$td-%1\$tY", now)
}

@JvmStatic
fun abs(symbolTable: SymbolTable, instruction: IR.Instruction) {
val op1Entry = symbolTable[instruction.op1]
Expand Down
Loading