From 84a195a29f0125f25a88a0ffbec10843647368f2 Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Sun, 9 Jun 2024 14:48:53 +0200 Subject: [PATCH] add variables! --- README.md | 13 ++++++++++--- f2.go | 29 +++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 16e201e..216dd1e 100644 --- a/README.md +++ b/README.md @@ -102,20 +102,27 @@ Conceptually clearer to have all the multiplications first and then all the divi - [x] Add show more info version - [x] Scalar multiplication and division - [ ] Program into a small device, like a calculator? -- [ ] Think of some way of calling bc -- [ ] Think how to integrate with squiggle.c to draw samples +- [-] Think of some way of calling bc +- [x] Think how to integrate with squiggle.c to draw samples + - [x] Copy the time to botec go code + - [ ] Define samplers + - [ ] Call those samplers when operating on distributions that can't be operted on algebraically - [ ] Think about how to draw a histogram from samples - [x] Display output more nicely, with K/M/B/T - [ ] Consider the following: make this into a stack-based DSL, with: - Variables that can be saved to and then displayed - Other types of distributions, particularly beta distributions? => But then this requires moving to bags of samples. It could still be ~instantaneous though. +- Figure out syntax for + - Maps + - Joint types + - Enums Some possible syntax for a more expressive stack-based DSL ``` 1B to 20B * 1 to 100 -/ beta(1, 2) +/ beta 1 2 # or b 1 2 =: x # content of the stack at this point saved into x 1 to 10 diff --git a/f2.go b/f2.go index 92794f0..a3c7120 100644 --- a/f2.go +++ b/f2.go @@ -31,7 +31,7 @@ func parseLineErr(err_msg string) (string, Dist, error) { fmt.Println(err_msg) return "", Dist{}, errors.New(err_msg) } -func parseLine(line string) (string, Dist, error) { +func parseLine(line string, vars map[string]Dist) (string, Dist, error) { words := strings.Split(strings.TrimSpace(line), " ") op := "" @@ -56,11 +56,16 @@ func parseLine(line string) (string, Dist, error) { case 0: return parseLineErr("Operator must have operand; can't operate on nothing") case 1: + var_word, var_word_exists := vars[words[0]] single_float, err1 := strconv.ParseFloat(words[0], 64) - if err1 != nil { - return parseLineErr("Trying to operate on a scalar, but scalar is not a float") + switch { + case var_word_exists: + dist = var_word + case err1 == nil: + dist = Dist{Type: "Lognormal", Lognormal: Lognormal{low: single_float, high: single_float}, Samples: nil} + case err1 != nil && !var_word_exists: + return parseLineErr("Trying to operate on a scalar, but scalar is neither a float nor a variable") } - dist = Dist{Type: "Lognormal", Lognormal: Lognormal{low: single_float, high: single_float}, Samples: nil} case 2: new_low, err1 := strconv.ParseFloat(words[0], 64) new_high, err2 := strconv.ParseFloat(words[1], 64) @@ -105,7 +110,7 @@ func joinDists(old_dist Dist, new_dist Dist, op string) (Dist, error) { default: fmt.Printf("For now, can't do anything besides multiplying lognormals\n") } - return old_dist, errors.New("Error blah blah") + return old_dist, errors.New("Can't combine distributions in this way") } /* Pretty print distributions */ @@ -157,6 +162,9 @@ func prettyPrintDist(dist Dist) { func main() { reader := bufio.NewReader(os.Stdin) old_dist := Dist{Type: "Lognormal", Lognormal: Lognormal{low: 1, high: 1}, Samples: nil} // Could also just be a scalar + vars := make(map[string]Dist) + // Could eventually be a more complex struct with: + // { Dist, VariableMaps, ConfigParams } or smth // fmt.Printf("Hello world") EventForLoop: @@ -175,17 +183,22 @@ EventForLoop: fmt.Println(general_err_msg) continue EventForLoop case words[0] == "debug" || words[0] == "d": - fmt.Printf("%v\n", old_dist) + fmt.Printf("Old dist: %v\n", old_dist) + fmt.Printf("Vars: %v\n", vars) + continue EventForLoop + case words[0] == "=:" && len(words) == 2: + // fmt.Println("Variables not yet implemented") + vars[words[1]] = old_dist // is this a copy? continue EventForLoop // Other possible cases: // Save to file // Sample n samples // Save stack to a variable? - // Define a function? No, too much of a nerdsnipe + // Define a function? No, too much of a nerdsnipea } } - op, new_dist, err := parseLine(input) + op, new_dist, err := parseLine(input, vars) if err != nil { continue EventForLoop }