You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
2.4 KiB
113 lines
2.4 KiB
2 years ago
|
package main
|
||
|
|
||
|
// Definitions of type structures in the interpreted language:
|
||
|
|
||
|
// NativeType Types in Go that the language can evaluate to
|
||
|
type NativeType interface {
|
||
|
float64
|
||
|
}
|
||
|
|
||
|
// Type A type specification in the language
|
||
|
type Type[TNative NativeType] interface {
|
||
|
String() string
|
||
|
}
|
||
|
|
||
|
// NumberType type specification for numbers in the language
|
||
|
type NumberType struct {
|
||
|
Type[float64]
|
||
|
}
|
||
|
|
||
|
func (n NumberType) IsNumberType() {}
|
||
|
func (n NumberType) String() string {
|
||
|
return "number"
|
||
|
}
|
||
|
|
||
|
// AST definitions:
|
||
|
|
||
|
// Node base for AST nodes
|
||
|
type Node interface {
|
||
|
}
|
||
|
|
||
|
// Expression subtree that evaluates to a single value of some type
|
||
|
type Expression[TNative NativeType, TValue Type[TNative]] interface {
|
||
|
Node
|
||
|
GetType() TValue
|
||
|
IsExpression()
|
||
|
}
|
||
|
|
||
|
// BinaryExpression subtree that has two subtrees, evaluates to a single value
|
||
|
type BinaryExpression[
|
||
|
TValueNative NativeType,
|
||
|
TValue Type[TValueNative],
|
||
|
TLeftNative NativeType,
|
||
|
TLeft Type[TLeftNative],
|
||
|
TRightNative NativeType,
|
||
|
TRight Type[TRightNative],
|
||
|
] interface {
|
||
|
Expression[TValueNative, TValue]
|
||
|
GetLeft() Expression[TLeftNative, TLeft]
|
||
|
GetRight() Expression[TRightNative, TRight]
|
||
|
}
|
||
|
|
||
|
// Definitions for values in the language
|
||
|
|
||
|
// Value base for values in th language
|
||
|
type Value[TNative NativeType, TValue Type[TNative]] interface {
|
||
|
GetType() TValue
|
||
|
GetValue() TNative
|
||
|
}
|
||
|
|
||
|
// NumberValue a numeric value in the language
|
||
|
type NumberValue struct {
|
||
|
Value float64
|
||
|
}
|
||
|
|
||
|
func (nv NumberValue) GetValue() float64 {
|
||
|
return nv.Value
|
||
|
}
|
||
|
func (nv NumberValue) GetType() NumberType {
|
||
|
return NumberType{}
|
||
|
}
|
||
|
|
||
|
// Number expression of a literal number in the language
|
||
|
type Number struct {
|
||
|
Expression[float64, NumberType]
|
||
|
Value float64
|
||
|
}
|
||
|
|
||
|
func (n Number) IsExpression() {}
|
||
|
func (n Number) GetType() NumberType {
|
||
|
return NumberType{}
|
||
|
}
|
||
|
|
||
|
// Add expression of the addition of two numbers in the language
|
||
|
type Add struct {
|
||
|
Left Expression[float64, NumberType]
|
||
|
Right Expression[float64, NumberType]
|
||
|
}
|
||
|
|
||
|
func (a Add) IsExpression() {}
|
||
|
func (a Add) GetType() NumberType {
|
||
|
return NumberType{}
|
||
|
}
|
||
|
func (a Add) GetLeft() Expression[float64, NumberType] {
|
||
|
return a.Left
|
||
|
}
|
||
|
func (a Add) GetRight() Expression[float64, NumberType] {
|
||
|
return a.Right
|
||
|
}
|
||
|
|
||
|
// Eval evaluator of the language
|
||
|
func Eval[TNative NativeType, TValue Type[TNative]](node Expression[TNative, TValue]) Value[TNative, TValue] {
|
||
|
switch node := node.(type) {
|
||
|
case Number:
|
||
|
return &NumberValue{Value: node.Value}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
}
|
||
|
|