From a2df4fbba448127ebac535413c913dd6c22ce236 Mon Sep 17 00:00:00 2001 From: garrettmills Date: Thu, 21 Apr 2022 08:54:30 -0500 Subject: [PATCH] Big bang --- README.md | 10 +++++ interp.go | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 README.md create mode 100644 interp.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..e3d534d --- /dev/null +++ b/README.md @@ -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 +``` + diff --git a/interp.go b/interp.go new file mode 100644 index 0000000..da788f3 --- /dev/null +++ b/interp.go @@ -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() { +} +