Adds license and fixes up version output

master
sloum 2 years ago
parent 6637891379
commit 700e899428

@ -10,7 +10,7 @@ type env struct {
vars
outer *env
}
func (e *env) Find(s symbol) *env {
if _, ok := e.vars[s]; ok {
return e

@ -42,8 +42,8 @@ func MergeLists(a ...expression) (expression, error) {
}
func escapeString(s string) string {
var out strings.Builder
for _, c := range []rune(s) {
var out strings.Builder
for _, c := range []rune(s) {
switch c {
case '\t':
out.WriteString("\\t")
@ -64,51 +64,51 @@ func escapeString(s string) string {
default:
out.WriteRune(c)
}
}
return out.String()
}
return out.String()
}
func unescapeString(s string) string {
var out strings.Builder
var out strings.Builder
escapeNumBase := 10
var altNum bool
var otherNum strings.Builder
var slash bool
for _, c := range []rune(s) {
if slash && !altNum {
switch c {
case 't':
out.WriteRune('\t')
case 'n':
out.WriteRune('\n')
case 'r':
out.WriteRune('\r')
case 'v':
out.WriteRune('\v')
case 'a':
out.WriteRune('\a')
case 'b':
out.WriteRune('\b')
case 'f':
out.WriteRune('\f')
var slash bool
for _, c := range []rune(s) {
if slash && !altNum {
switch c {
case 't':
out.WriteRune('\t')
case 'n':
out.WriteRune('\n')
case 'r':
out.WriteRune('\r')
case 'v':
out.WriteRune('\v')
case 'a':
out.WriteRune('\a')
case 'b':
out.WriteRune('\b')
case 'f':
out.WriteRune('\f')
case '0':
escapeNumBase = 8
altNum = true
continue
case '1', '3', '4', '2', '5', '6' ,'7', '8', '9':
case '1', '3', '4', '2', '5', '6', '7', '8', '9':
altNum = true
otherNum.WriteRune(c)
continue
default:
out.WriteRune(c)
}
slash = false
default:
out.WriteRune(c)
}
slash = false
} else if slash {
switch c {
case '0', '1', '3', '4', '2', '5', '6' ,'7', '8', '9':
case '0', '1', '3', '4', '2', '5', '6', '7', '8', '9':
otherNum.WriteRune(c)
case 'x':
if otherNum.String() == "" {
@ -133,13 +133,13 @@ func unescapeString(s string) string {
out.WriteRune(c)
}
}
} else if c == '\\' {
slash = true
} else {
out.WriteRune(c)
}
}
return out.String()
} else if c == '\\' {
slash = true
} else {
out.WriteRune(c)
}
}
return out.String()
}
func SafeExit(code int) {
@ -159,7 +159,9 @@ func SafeExit(code int) {
openFiles[i].Open = false
}
}
line.Close()
if usingRepl {
line.Close()
}
os.Exit(code)
}
@ -170,4 +172,3 @@ func StringSliceToExpressionSlice(s []string) expression {
}
return e
}

@ -5,9 +5,9 @@ import (
)
type proc struct {
params expression
body expression
en *env
params expression
body expression
en *env
}
func eval(exp expression, en *env) (value expression) {
@ -40,7 +40,7 @@ func eval(exp expression, en *env) (value expression) {
if len(e) < 2 {
panic("Invalid 'cond' syntax - too few arguments")
}
CondLoop:
CondLoop:
for _, exp := range e[1:] {
switch i := exp.(type) {
case []expression:
@ -96,11 +96,11 @@ func eval(exp expression, en *env) (value expression) {
values[i] = eval(x, en)
}
value = apply(eval(e[0], en), values)
}
default:
}
default:
panic("Unknown expression type encountered during EVAL")
}
return
}
return
}
func apply(procedure expression, args []expression) (value expression) {

@ -19,7 +19,7 @@ func eatSingleLineComment(r *strings.Reader) {
}
func eatWhiteSpace(r *strings.Reader) {
for ;r.Len() > 0; {
for r.Len() > 0 {
c, _, err := r.ReadRune()
if err != nil {
panic("Lexing error while eating whitespace")
@ -78,7 +78,7 @@ func eatQuasiQuote(r *strings.Reader) []string {
depth := 0
var currentString string
Loop:
Loop:
for r.Len() > 0 {
c, _, err := r.ReadRune()
if err != nil {
@ -138,8 +138,8 @@ func Tokenize(s string) []string {
reader := strings.NewReader(s)
tokens := make([]string, 0)
var currentString string
TokenizationLoop:
for ;reader.Len() > 0; {
TokenizationLoop:
for reader.Len() > 0 {
c, _, err := reader.ReadRune()
if err != nil {
break TokenizationLoop
@ -180,6 +180,5 @@ func Tokenize(s string) []string {
}
}
return tokens
}

@ -18,7 +18,7 @@ import (
var stdLibrary = vars{
"PI": number(math.Pi),
"E": number(math.E),
"E": number(math.E),
"positive?": func(a ...expression) expression {
if len(a) > 0 {
if n, ok := a[0].(number); ok {
@ -319,7 +319,7 @@ var stdLibrary = vars{
if len(a) == 0 {
panic("'pair?' expected a value, but no value was given")
}
switch i:= a[0].(type) {
switch i := a[0].(type) {
case []expression:
return len(i) > 0
default:
@ -348,7 +348,7 @@ var stdLibrary = vars{
return false
}
},
"length": func (a ...expression) expression {
"length": func(a ...expression) expression {
switch i := a[0].(type) {
case []expression:
return number(len(i))
@ -471,7 +471,7 @@ var stdLibrary = vars{
}
return mainList
},
"list": eval(Parse("(lambda z z)").([]expression)[0],&globalenv),
"list": eval(Parse("(lambda z z)").([]expression)[0], &globalenv),
"list-ref": func(a ...expression) expression {
if len(a) < 2 {
panic("'list-ref' expects 2 arguments, a list and a number, no arguments were given")
@ -497,7 +497,7 @@ var stdLibrary = vars{
case []expression:
out := make([]expression, len(l))
for i, n := range l {
j := len(l)- i - 1
j := len(l) - i - 1
out[j] = n
}
return out
@ -892,7 +892,7 @@ var stdLibrary = vars{
panic("'substring' expects a number as its second argument")
}
if n1 < 0 || n1 >= n2{
if n1 < 0 || n1 >= n2 {
panic("start position of 'substring' is out of range")
}
@ -1000,13 +1000,13 @@ var stdLibrary = vars{
panic("'file-open-write' expects a filepath, no filepath was given")
}
if fp, ok := a[0].(string); ok {
flags := os.O_CREATE | os.O_WRONLY
flags := os.O_CREATE | os.O_WRONLY
if len(a) >= 2 {
if b, ok := a[1].(bool); ok && b {
flags = flags | os.O_TRUNC
}
}
f, err := os.OpenFile(fp, flags ,0664)
f, err := os.OpenFile(fp, flags, 0664)
if err != nil {
return false
}
@ -1041,7 +1041,7 @@ var stdLibrary = vars{
}
panic("'file-append-to' expects a filepath, as a string, as its first argument")
},
"open?": func (a ...expression) expression {
"open?": func(a ...expression) expression {
if len(a) < 1 {
panic("'open?' expects an IO handle, no argument was given")
}
@ -1143,7 +1143,7 @@ var stdLibrary = vars{
if usetls {
conf := &tls.Config{InsecureSkipVerify: true}
if timeout > 0 {
tlsconn, err = tls.DialWithDialer(&net.Dialer{Timeout: time.Duration(timeout)*time.Second}, "tcp", addr, conf)
tlsconn, err = tls.DialWithDialer(&net.Dialer{Timeout: time.Duration(timeout) * time.Second}, "tcp", addr, conf)
if err != nil {
return false
}
@ -1155,7 +1155,7 @@ var stdLibrary = vars{
}
} else {
if timeout > 0 {
conn, err = net.DialTimeout("tcp", addr, time.Duration(timeout) * time.Second)
conn, err = net.DialTimeout("tcp", addr, time.Duration(timeout)*time.Second)
if err != nil {
return false
}
@ -1247,7 +1247,7 @@ var stdLibrary = vars{
if len(a) >= 2 {
switch s := a[1].(type) {
case string:
u.RawQuery= s
u.RawQuery = s
case symbol:
u.RawQuery = string(s)
default:
@ -1307,9 +1307,12 @@ var stdLibrary = vars{
}
return u.Scheme
},
"license": func(a ...expression) expression {
fmt.Println(licenseText)
return make([]expression, 0)
},
}
/*
TODO:
@ -1416,4 +1419,3 @@ System Based:
[x] equal? (compares any two things)
*/

@ -0,0 +1,11 @@
package main
const licenseText string = `
Copyright © 2021 sloum <sloum@rawtext.club>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
`

@ -1,13 +1,12 @@
package main
import (
// "bufio"
"flag"
"fmt"
"fmt"
"io/ioutil"
"os"
"os"
"strconv"
"strings"
"strings"
ln "github.com/peterh/liner"
)
@ -17,14 +16,14 @@ var replCounter int = 0
var line *ln.State
var Version string
var VersionHash string
var usingRepl bool
// Used in the repl so that input can continue,
// but potentially useful in other situations
func RecoverError() {
if r := recover(); r != nil {
fmt.Fprintf(os.Stderr, "\033[31mOops! %s\033[0m\n", r)
}
if r := recover(); r != nil {
fmt.Fprintf(os.Stderr, "\033[31mOops! %s\033[0m\n", r)
}
}
func String(v expression) string {
@ -35,13 +34,13 @@ func String(v expression) string {
l[i] = String(x)
}
return "(" + strings.Join(l, " ") + ")"
case string:
return fmt.Sprintf("\"%s\"", v)
case bool:
if v {
return "#t"
}
return "#f"
case string:
return fmt.Sprintf("\"%s\"", v)
case bool:
if v {
return "#t"
}
return "#f"
case number:
return strconv.FormatFloat(float64(v), 'f', -1, 64)
default:
@ -51,21 +50,21 @@ func String(v expression) string {
func Init() {
openFiles = make([]*IOHandle, 0, 5)
globalenv = env{stdLibrary, nil}
globalenv = env{stdLibrary, nil}
}
func outputResult(txt string) {
defer RecoverError()
defer RecoverError()
parsed := Parse(txt)
for i := range parsed.([]expression) {
replCounter++
evaluated := eval(parsed.([]expression)[i], &globalenv)
fmt.Printf("#%d=> %s\n",replCounter, String(evaluated))
fmt.Printf("#%d=> %s\n", replCounter, String(evaluated))
}
}
func RunCommand(s string) {
if strings.Count(s, "(") != strings.Count(s,")") {
if strings.Count(s, "(") != strings.Count(s, ")") {
fmt.Fprintf(os.Stderr, "Invalid input string, uneven parens")
SafeExit(1)
}
@ -111,10 +110,20 @@ func prompt(ln *ln.State, cont bool) string {
return val
}
func PrintVersion() {
if Version != "" {
fmt.Printf("slope\n-----\nVersion Number: 0.%s.0\nBuild Hash: %s\n(c) 2021 sloum, see license with: (license)\n", Version, VersionHash)
} else {
fmt.Print("slope\n-----\nVersion: Custom (not hash based)\n(c) 2021 sloum, see license\n")
}
}
func Repl() {
usingRepl = true
line = ln.NewLiner()
defer line.Close()
fmt.Printf("slope version %s - %s\n", Version, VersionHash)
PrintVersion()
fmt.Printf("Type (exit) to quit\n\n")
var text strings.Builder
var cont bool
@ -135,11 +144,17 @@ func Repl() {
}
func main() {
verFlag := flag.Bool("v", false, "Print version information and exit")
runCommand := flag.String("run", "", "A quoted string of commands to run and get output from")
flag.Parse()
args := flag.Args()
Init()
if *verFlag {
PrintVersion()
os.Exit(0)
}
Init()
if *runCommand != "" {
RunCommand(*runCommand)

@ -5,17 +5,16 @@ import (
"strings"
)
type expression interface{}
type IOHandle struct {
Obj expression
Obj expression
Open bool
}
type number float64
type symbol string
type err string
type number float64
type symbol string
type err string
func Parse(s string) expression {
tokens := Tokenize(s)
@ -77,7 +76,7 @@ func parserRead(tokens *[]string) expression {
return number(i)
}
}
if strings.HasPrefix(token, "0") {
i, err := strconv.ParseInt(token, 8, 0)
if err == nil {
@ -91,7 +90,7 @@ func parserRead(tokens *[]string) expression {
}
if strings.HasPrefix(token, "\"") && strings.HasSuffix(token, "\"") {
return token[1:len(token)-1]
return token[1 : len(token)-1]
} else if token == "#t" {
return true
} else if token == "#f" {

Loading…
Cancel
Save