Skip to content

Commit

Permalink
Eval support (#538)
Browse files Browse the repository at this point in the history
Co-authored-by: Benjamin Gaidioz <[email protected]>
  • Loading branch information
miguelbranco80 and bgaidioz authored Feb 7, 2025
1 parent 61a3b47 commit 651faa3
Show file tree
Hide file tree
Showing 16 changed files with 2,842 additions and 1,280 deletions.
74 changes: 23 additions & 51 deletions compiler/src/main/scala/com/rawlabs/compiler/CompilerService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,12 @@

package com.rawlabs.compiler

import com.rawlabs.protocol.raw.{Type, Value}
import org.graalvm.polyglot.Engine

import java.io.OutputStream
import scala.collection.mutable
import com.rawlabs.utils.core.{RawException, RawService, RawSettings}

// Exception that wraps the underlying error so that it includes the extra debug info.
final class CompilerServiceException(
message: String,
val debugInfo: List[(String, String)] = List.empty,
cause: Throwable = null
) extends RawException(message, cause) {

def this(t: Throwable, debugInfo: List[(String, String)]) = this(t.getMessage, debugInfo, t)

def this(t: Throwable, environment: ProgramEnvironment) = {
this(t, CompilerService.getDebugInfo(environment))
}

def this(t: Throwable) = this(t.getMessage, cause = t)

}
import com.rawlabs.utils.core.{RawService, RawSettings}

object CompilerService {

Expand Down Expand Up @@ -90,19 +74,6 @@ object CompilerService {
}
}

def getDebugInfo(environment: ProgramEnvironment): List[(String, String)] = {
List(
"Trace ID" -> environment.maybeTraceId.getOrElse("<undefined>"),
"Arguments" -> environment.maybeArguments
.map(args => args.map { case (k, v) => s"$k -> $v" }.mkString("\n"))
.getOrElse("<undefined>"),
"Uid" -> environment.uid.toString,
"Scopes" -> environment.scopes.mkString(","),
"Options" -> environment.options.map { case (k, v) => s"$k -> $v" }.mkString("\n")
//"Settings" -> runtimeContext.settings.toString
)
}

}

trait CompilerService extends RawService {
Expand All @@ -112,24 +83,27 @@ trait CompilerService extends RawService {
def language: Set[String]

// Get the description of a source program.
@throws[CompilerServiceException]
def getProgramDescription(
source: String,
environment: ProgramEnvironment
): GetProgramDescriptionResponse
): Either[List[ErrorMessage], ProgramDescription]

// Execute a source program and write the results to the output stream.
@throws[CompilerServiceException]
def execute(
source: String,
environment: ProgramEnvironment,
maybeDecl: Option[String],
outputStream: OutputStream,
maxRows: Option[Long] = None
): ExecutionResponse
): Either[ExecutionError, ExecutionSuccess]

def eval(
source: String,
environment: ProgramEnvironment,
maybeDecl: Option[String]
): Either[ExecutionError, EvalSuccess]

// Format a source program.
@throws[CompilerServiceException]
def formatCode(
source: String,
environment: ProgramEnvironment,
Expand All @@ -138,15 +112,13 @@ trait CompilerService extends RawService {
): FormatCodeResponse

// Auto-complete a source program.
@throws[CompilerServiceException]
def dotAutoComplete(
source: String,
environment: ProgramEnvironment,
position: Pos
): AutoCompleteResponse

// Auto-complete a word in a source program.
@throws[CompilerServiceException]
def wordAutoComplete(
source: String,
environment: ProgramEnvironment,
Expand All @@ -155,38 +127,38 @@ trait CompilerService extends RawService {
): AutoCompleteResponse

// Get the hover information for a source program.
@throws[CompilerServiceException]
def hover(source: String, environment: ProgramEnvironment, position: Pos): HoverResponse

// Rename an identifier in a source program.
@throws[CompilerServiceException]
def rename(source: String, environment: ProgramEnvironment, position: Pos): RenameResponse

// Go to definition of an identifier in a source program.
@throws[CompilerServiceException]
def goToDefinition(source: String, environment: ProgramEnvironment, position: Pos): GoToDefinitionResponse

// Validate a source program.
@throws[CompilerServiceException]
def validate(source: String, environment: ProgramEnvironment): ValidateResponse

// Validate a source program for the AI service.
@throws[CompilerServiceException]
def aiValidate(source: String, environment: ProgramEnvironment): ValidateResponse

}

final case class Pos(line: Int, column: Int)

sealed trait GetProgramDescriptionResponse
final case class GetProgramDescriptionFailure(errors: List[ErrorMessage]) extends GetProgramDescriptionResponse
final case class GetProgramDescriptionSuccess(programDescription: ProgramDescription)
extends GetProgramDescriptionResponse
final case class ExecutionSuccess(complete: Boolean)

sealed trait ExecutionResponse
final case class ExecutionSuccess(complete: Boolean) extends ExecutionResponse
final case class ExecutionValidationFailure(errors: List[ErrorMessage]) extends ExecutionResponse
final case class ExecutionRuntimeFailure(error: String) extends ExecutionResponse
sealed trait ExecutionError
object ExecutionError {
final case class ValidationError(errors: List[ErrorMessage]) extends ExecutionError

final case class RuntimeError(error: String) extends ExecutionError
}

sealed trait EvalSuccess
object EvalSuccess {
final case class IteratorValue(innerType: Type, valueIterator: Iterator[Value] with AutoCloseable) extends EvalSuccess
final case class ResultValue(valueType: Type, value: Value) extends EvalSuccess
}

final case class FormatCodeResponse(code: Option[String])
final case class HoverResponse(completion: Option[Completion])
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/main/scala/com/rawlabs/compiler/RawValues.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@ final case class RawInterval(
seconds: Int,
millis: Int
) extends RawValue
final case class RawRecord(fields: Map[String, RawValue]) extends RawValue
final case class RawRecord(atts: Seq[RawRecordAttr]) extends RawValue
final case class RawRecordAttr(idn: String, value: RawValue)
final case class RawList(values: List[RawValue]) extends RawValue
153 changes: 153 additions & 0 deletions compiler/src/main/scala/com/rawlabs/compiler/TypeConverter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* Copyright 2024 RAW Labs S.A.
*
* Use of this software is governed by the Business Source License
* included in the file licenses/BSL.txt.
*
* As of the Change Date specified in that file, in accordance with
* the Business Source License, use of this software will be governed
* by the Apache License, Version 2.0, included in the file
* licenses/APL.txt.
*/

package com.rawlabs.compiler

import com.rawlabs.protocol.raw.{
AnyType,
AttrType,
BinaryType,
BoolType,
ByteType,
DateType,
DecimalType,
DoubleType,
FloatType,
IntType,
IntervalType,
IterableType,
ListType,
LongType,
OrType,
RecordType,
ShortType,
StringType,
TimeType,
TimestampType,
Type,
UndefinedType
}

import scala.collection.JavaConverters._

object TypeConverter {

/**
* Converts a raw compiler API type to a gRPC protocol type.
*
* @param t the raw compiler API type
* @return the gRPC protocol type
*/
def toProtocolType(t: com.rawlabs.compiler.RawType): Type = {
t match {
case com.rawlabs.compiler.RawAnyType() => Type.newBuilder().setAny(AnyType.newBuilder().build()).build()
case com.rawlabs.compiler.RawUndefinedType(nullable, triable) => Type
.newBuilder()
.setUndefined(UndefinedType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawByteType(nullable, triable) => Type
.newBuilder()
.setByte(ByteType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawShortType(nullable, triable) => Type
.newBuilder()
.setShort(ShortType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawIntType(nullable, triable) => Type
.newBuilder()
.setInt(IntType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawLongType(nullable, triable) => Type
.newBuilder()
.setLong(LongType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawFloatType(nullable, triable) => Type
.newBuilder()
.setFloat(FloatType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawDoubleType(nullable, triable) => Type
.newBuilder()
.setDouble(DoubleType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawDecimalType(nullable, triable) => Type
.newBuilder()
.setDecimal(DecimalType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawBoolType(nullable, triable) => Type
.newBuilder()
.setBool(BoolType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawStringType(nullable, triable) => Type
.newBuilder()
.setString(StringType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawBinaryType(nullable, triable) => Type
.newBuilder()
.setBinary(BinaryType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawDateType(nullable, triable) => Type
.newBuilder()
.setDate(DateType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawTimeType(nullable, triable) => Type
.newBuilder()
.setTime(TimeType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawTimestampType(nullable, triable) => Type
.newBuilder()
.setTimestamp(TimestampType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawIntervalType(nullable, triable) => Type
.newBuilder()
.setInterval(IntervalType.newBuilder().setNullable(nullable).setTriable(triable).build())
.build()
case com.rawlabs.compiler.RawRecordType(atts, nullable, triable) => Type
.newBuilder()
.setRecord(
RecordType
.newBuilder()
.addAllAtts(
atts.map(f => AttrType.newBuilder().setIdn(f.idn).setTipe(toProtocolType(f.tipe)).build()).asJava
)
.setNullable(nullable)
.setTriable(triable)
.build()
)
.build()
case com.rawlabs.compiler.RawListType(t, nullable, triable) => Type
.newBuilder()
.setList(
ListType.newBuilder().setInnerType(toProtocolType(t)).setNullable(nullable).setTriable(triable).build()
)
.build()
case com.rawlabs.compiler.RawIterableType(t, nullable, triable) => Type
.newBuilder()
.setIterable(
IterableType.newBuilder().setInnerType(toProtocolType(t)).setNullable(nullable).setTriable(triable).build()
)
.build()
case com.rawlabs.compiler.RawOrType(ors, nullable, triable) => Type
.newBuilder()
.setOr(
OrType
.newBuilder()
.addAllOrs(ors.map(toProtocolType).asJava)
.setNullable(nullable)
.setTriable(triable)
.build()
)
.build()
case t => throw new AssertionError(s"support for $t not implemented yet")
}
}

}
Loading

0 comments on commit 651faa3

Please sign in to comment.