Big bang
This commit is contained in:
commit
a2df4fbba4
10
README.md
Normal file
10
README.md
Normal 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
112
interp.go
Normal 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() {
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user