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() { }