This commit is contained in:
Garrett Mills 2022-04-21 08:54:30 -05:00
commit a2df4fbba4
2 changed files with 122 additions and 0 deletions

10
README.md Normal file
View File

@ -0,0 +1,10 @@
Minimal example for my StackOverflow question here:
https://stackoverflow.com/questions/71955121/how-to-type-switch-values-with-generic-types
To trigger the issue:
```
go run interp.go
```

112
interp.go Normal file
View File

@ -0,0 +1,112 @@
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() {
}