mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
Structs can be compiled and executed in the vm! structs are just syntactic sugar for a set of variables for now.
This commit is contained in:
parent
44f9d5e69e
commit
1e9586f635
@ -1,6 +1,5 @@
|
||||
package prog8.ast.processing
|
||||
|
||||
import com.sun.org.apache.bcel.internal.generic.ISTORE
|
||||
import prog8.ast.*
|
||||
import prog8.ast.base.*
|
||||
import prog8.ast.base.printWarning
|
||||
@ -426,7 +425,7 @@ internal class AstChecker(private val program: Program,
|
||||
checkResult.add(ExpressionError("assignment value is invalid or has no proper datatype", assignment.value.position))
|
||||
}
|
||||
else
|
||||
checkAssignmentCompatible(targetDatatype, sourceDatatype, assignment.value, assignment.position)
|
||||
checkAssignmentCompatible(targetDatatype, sourceDatatype, assignment.value, target, assignment.position)
|
||||
}
|
||||
}
|
||||
return assignment
|
||||
@ -1138,7 +1137,11 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
return err("invalid float array initialization value ${value.type}, expected $targetDt")
|
||||
}
|
||||
DataType.STRUCT -> TODO("struct dt")
|
||||
DataType.STRUCT -> {
|
||||
if(value.type!=DataType.STRUCT)
|
||||
return err("cannot assign a normal value to a struct")
|
||||
TODO("check struct, $value ")
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -1195,10 +1198,11 @@ internal class AstChecker(private val program: Program,
|
||||
private fun checkAssignmentCompatible(targetDatatype: DataType,
|
||||
sourceDatatype: DataType,
|
||||
sourceValue: IExpression,
|
||||
target: AssignTarget,
|
||||
position: Position) : Boolean {
|
||||
|
||||
if(sourceValue is RangeExpr)
|
||||
checkResult.add(SyntaxError("can't assign a range value", position))
|
||||
checkResult.add(SyntaxError("can't assign a range value to something else", position))
|
||||
|
||||
val result = when(targetDatatype) {
|
||||
DataType.BYTE -> sourceDatatype== DataType.BYTE
|
||||
@ -1208,6 +1212,17 @@ internal class AstChecker(private val program: Program,
|
||||
DataType.FLOAT -> sourceDatatype in NumericDatatypes
|
||||
DataType.STR -> sourceDatatype== DataType.STR
|
||||
DataType.STR_S -> sourceDatatype== DataType.STR_S
|
||||
DataType.STRUCT -> {
|
||||
// for now we've decided you cannot assign struct by-value.
|
||||
// if(sourceDatatype==DataType.STRUCT) {
|
||||
// val sourcename = (sourceValue as IdentifierReference).nameInSource
|
||||
// val vd1 = program.namespace.lookup(sourcename, target) as? VarDecl
|
||||
// val targetname = target.identifier!!.nameInSource
|
||||
// val vd2 = program.namespace.lookup(targetname, target) as? VarDecl
|
||||
// return vd1?.struct == vd2?.struct
|
||||
// }
|
||||
false
|
||||
}
|
||||
else -> checkResult.add(SyntaxError("cannot assign new value to variable of type $targetDatatype", position))
|
||||
}
|
||||
|
||||
|
@ -12,10 +12,14 @@ import kotlin.math.*
|
||||
|
||||
class BuiltinFunctionParam(val name: String, val possibleDatatypes: Set<DataType>)
|
||||
|
||||
|
||||
typealias ConstExpressionCaller = (args: List<IExpression>, position: Position, program: Program) -> LiteralValue
|
||||
|
||||
|
||||
class FunctionSignature(val pure: Boolean, // does it have side effects?
|
||||
val parameters: List<BuiltinFunctionParam>,
|
||||
val returntype: DataType?,
|
||||
val constExpressionFunc: ((args: List<IExpression>, position: Position, program: Program) -> LiteralValue)? = null)
|
||||
val constExpressionFunc: ConstExpressionCaller? = null)
|
||||
|
||||
|
||||
val BuiltinFunctions = mapOf(
|
||||
|
@ -265,7 +265,7 @@ class AstVm(val program: Program) {
|
||||
class LoopControlJump(val identifier: IdentifierReference?, val address: Int?, val generatedLabel: String?) : Exception()
|
||||
|
||||
|
||||
internal fun executeSubroutine(sub: Subroutine, arguments: List<RuntimeValue>, startlabel: Label?=null): RuntimeValue? {
|
||||
internal fun executeSubroutine(sub: Subroutine, arguments: List<RuntimeValue>, startAtLabel: Label?=null): RuntimeValue? {
|
||||
if(sub.isAsmSubroutine) {
|
||||
return performSyscall(sub, arguments)
|
||||
}
|
||||
@ -282,10 +282,10 @@ class AstVm(val program: Program) {
|
||||
}
|
||||
|
||||
val statements = sub.statements.iterator()
|
||||
if(startlabel!=null) {
|
||||
if(startAtLabel!=null) {
|
||||
do {
|
||||
val stmt = statements.next()
|
||||
} while(stmt!==startlabel)
|
||||
} while(stmt!==startAtLabel)
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -13,10 +13,15 @@ import prog8.vm.RuntimeValue
|
||||
import prog8.vm.RuntimeValueRange
|
||||
import kotlin.math.abs
|
||||
|
||||
|
||||
typealias BuiltinfunctionCaller = (name: String, args: List<RuntimeValue>, flags: StatusFlags) -> RuntimeValue?
|
||||
typealias SubroutineCaller = (sub: Subroutine, args: List<RuntimeValue>, startAtLabel: Label?) -> RuntimeValue?
|
||||
|
||||
|
||||
class EvalContext(val program: Program, val mem: Memory, val statusflags: StatusFlags,
|
||||
val runtimeVars: RuntimeVariables,
|
||||
val performBuiltinFunction: (String, List<RuntimeValue>, StatusFlags) -> RuntimeValue?,
|
||||
val executeSubroutine: (sub: Subroutine, args: List<RuntimeValue>, startlabel: Label?) -> RuntimeValue?)
|
||||
val performBuiltinFunction: BuiltinfunctionCaller,
|
||||
val executeSubroutine: SubroutineCaller)
|
||||
|
||||
fun evaluate(expr: IExpression, ctx: EvalContext): RuntimeValue {
|
||||
val constval = expr.constValue(ctx.program)
|
||||
@ -96,6 +101,9 @@ fun evaluate(expr: IExpression, ctx: EvalContext): RuntimeValue {
|
||||
if(variable is VarDecl) {
|
||||
if(variable.type==VarDeclType.VAR)
|
||||
return ctx.runtimeVars.get(variable.definingScope(), variable.name)
|
||||
else if(variable.type==VarDeclType.STRUCT) {
|
||||
throw VmExecutionException("cannot process structs by-value. at ${expr.position}")
|
||||
}
|
||||
else {
|
||||
val address = ctx.runtimeVars.getMemoryAddress(variable.definingScope(), variable.name)
|
||||
return when(variable.datatype) {
|
||||
|
@ -4,6 +4,7 @@ import prog8.ast.*
|
||||
import prog8.ast.base.*
|
||||
import prog8.ast.expressions.LiteralValue
|
||||
import prog8.ast.processing.IAstModifyingVisitor
|
||||
import prog8.ast.statements.StructDecl
|
||||
import prog8.ast.statements.VarDecl
|
||||
import prog8.compiler.HeapValues
|
||||
import prog8.vm.RuntimeValue
|
||||
@ -34,19 +35,25 @@ class VariablesCreator(private val runtimeVariables: RuntimeVariables, private v
|
||||
}
|
||||
|
||||
override fun visit(decl: VarDecl): IStatement {
|
||||
when(decl.type) {
|
||||
// we can assume the value in the vardecl already has been converted into a constant LiteralValue here.
|
||||
VarDeclType.VAR -> {
|
||||
val value = RuntimeValue.from(decl.value as LiteralValue, heap)
|
||||
runtimeVariables.define(decl.definingScope(), decl.name, value)
|
||||
// if the decl is part of a struct, just skip it
|
||||
if(decl.parent !is StructDecl) {
|
||||
when (decl.type) {
|
||||
// we can assume the value in the vardecl already has been converted into a constant LiteralValue here.
|
||||
VarDeclType.VAR -> {
|
||||
println("$decl")
|
||||
val value = RuntimeValue.from(decl.value as LiteralValue, heap)
|
||||
runtimeVariables.define(decl.definingScope(), decl.name, value)
|
||||
}
|
||||
VarDeclType.MEMORY -> {
|
||||
runtimeVariables.defineMemory(decl.definingScope(), decl.name, (decl.value as LiteralValue).asIntegerValue!!)
|
||||
}
|
||||
VarDeclType.CONST -> {
|
||||
// consts should have been const-folded away
|
||||
}
|
||||
VarDeclType.STRUCT -> {
|
||||
// struct vardecl can be skipped because its members have been flattened out
|
||||
}
|
||||
}
|
||||
VarDeclType.MEMORY -> {
|
||||
runtimeVariables.defineMemory(decl.definingScope(), decl.name, (decl.value as LiteralValue).asIntegerValue!!)
|
||||
}
|
||||
VarDeclType.CONST -> {
|
||||
// consts should have been const-folded away
|
||||
}
|
||||
VarDeclType.STRUCT -> TODO("struct decltype")
|
||||
}
|
||||
return super.visit(decl)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
uword derp
|
||||
|
||||
Color foreground ; = [0,1,2] @todo init values
|
||||
Color background
|
||||
|
Loading…
Reference in New Issue
Block a user