From a49573dd2726eae0ea6397bdf67ade318854d730 Mon Sep 17 00:00:00 2001 From: Steve Kemp Date: Sun, 6 Nov 2022 12:36:36 +0200 Subject: [PATCH] Allow hexadecimal/binary literals. This closes #78 by adding native support for hexadecimal and binary literals. For example: * `(print 0xff)` * `(print 0b00000010)` --- eval/eval.go | 16 ++++++++++++++++ eval/eval_test.go | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/eval/eval.go b/eval/eval.go index 5c13752..0a9292d 100644 --- a/eval/eval.go +++ b/eval/eval.go @@ -188,6 +188,22 @@ func (ev *Eval) atom(token string) primitive.Primitive { return primitive.Error(fmt.Sprintf("invalid character literal: %s", lit)) } + // See if this is a number with a hex/binary prefix + based := strings.ToLower(token) + if strings.HasPrefix(based, "0x") || strings.HasPrefix(based, "0b") { + + // If so then parse as an integer + n, err := strconv.ParseInt(based, 0, 32) + if err == nil { + + // Assuming it worked save it in our interned + // table and return it. + num := primitive.Number(n) + ev.symbols[token] = num + return num + } + } + // Is it a number? f, err := strconv.ParseFloat(token, 64) if err == nil { diff --git a/eval/eval_test.go b/eval/eval_test.go index aa7acd0..5f01ee8 100644 --- a/eval/eval_test.go +++ b/eval/eval_test.go @@ -101,6 +101,20 @@ func TestEvaluate(t *testing.T) { {"#!/usr/bin/yal\n", "nil"}, {"#!/usr/bin/yal\n#t", "#t"}, + // integers: in hex + {"0xff", "255"}, + {"0xFF", "255"}, + {"0xFf", "255"}, + {"0xfF", "255"}, + + // integers: in binary + {"0b00000000", "0"}, + {"0b00000001", "1"}, + {"0b00000010", "2"}, + {"0b00000100", "4"}, + {"0b00001000", "8"}, + {"0b10000000", "128"}, + // bools {"#t", "#t"}, {"true", "#t"},