init commit
This commit is contained in:
commit
143b17a6c1
70
hash_map/hash_map.go
Normal file
70
hash_map/hash_map.go
Normal file
@ -0,0 +1,70 @@
|
||||
package hash_map
|
||||
|
||||
import (
|
||||
"mal-go/utils"
|
||||
"maps"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TODO: replace COW with proper HashArrayMappedTrie impelmentation of PersistentHashMap
|
||||
|
||||
type HashMap struct {
|
||||
_map map[any]any
|
||||
}
|
||||
|
||||
func New() *HashMap {
|
||||
return new(HashMap).Init()
|
||||
}
|
||||
|
||||
func Init(this *HashMap) *HashMap {
|
||||
this._map = make(map[any]any)
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *HashMap) Init() *HashMap {
|
||||
return Init(this)
|
||||
}
|
||||
|
||||
func Clone(this *HashMap) *HashMap {
|
||||
if this == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
newMap := New().Init()
|
||||
maps.Copy(newMap._map, this._map)
|
||||
return newMap
|
||||
}
|
||||
|
||||
func (this *HashMap) Clone() *HashMap {
|
||||
return Clone(this)
|
||||
}
|
||||
|
||||
func Conj(this *HashMap, key any, val any) *HashMap {
|
||||
newMap := this.Clone()
|
||||
newMap._map[key] = val
|
||||
return newMap
|
||||
}
|
||||
|
||||
func (this *HashMap) Conj(key any, val any) *HashMap {
|
||||
return Conj(this, key, val)
|
||||
}
|
||||
|
||||
func String(this *HashMap) string {
|
||||
if this == nil {
|
||||
return "{}"
|
||||
}
|
||||
var sb strings.Builder
|
||||
sb.WriteRune('{')
|
||||
for key, val := range this._map {
|
||||
sb.WriteString(utils.Stringify(key))
|
||||
sb.WriteRune(' ')
|
||||
sb.WriteString(utils.Stringify(val))
|
||||
sb.WriteRune(',')
|
||||
sb.WriteRune(' ')
|
||||
}
|
||||
return sb.String()[:sb.Len()-2] + "}"
|
||||
}
|
||||
|
||||
func (this *HashMap) String() string {
|
||||
return String(this)
|
||||
}
|
||||
40
keyword/keyword.go
Normal file
40
keyword/keyword.go
Normal file
@ -0,0 +1,40 @@
|
||||
package keyword
|
||||
|
||||
var intern_map map[string]*Keyword
|
||||
|
||||
type Keyword struct {
|
||||
ns string
|
||||
keyword string
|
||||
}
|
||||
|
||||
func Intern(keyword string) *Keyword {
|
||||
return Intern_ns("", keyword)
|
||||
}
|
||||
|
||||
func Intern_ns(ns string, keyword string) *Keyword {
|
||||
combined_str := ns + "/" + keyword
|
||||
existingkeyword, ok := intern_map[combined_str]
|
||||
if ok {
|
||||
return existingkeyword
|
||||
} else {
|
||||
newkeyword := new(Keyword)
|
||||
newkeyword.ns = ns
|
||||
newkeyword.keyword = keyword
|
||||
if intern_map == nil {
|
||||
intern_map = make(map[string]*Keyword)
|
||||
}
|
||||
intern_map[combined_str] = newkeyword
|
||||
return newkeyword
|
||||
}
|
||||
}
|
||||
|
||||
func String(this *Keyword) string {
|
||||
if this.ns == "" {
|
||||
return ":" + this.keyword
|
||||
}
|
||||
return ":" + this.ns + "/" + this.keyword
|
||||
}
|
||||
|
||||
func (this *Keyword) String() string {
|
||||
return String(this)
|
||||
}
|
||||
72
list/list.go
Normal file
72
list/list.go
Normal file
@ -0,0 +1,72 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type List struct {
|
||||
Value any
|
||||
next *List
|
||||
}
|
||||
|
||||
func New(val any) *List {
|
||||
return new(List).Init(val)
|
||||
}
|
||||
|
||||
func (this *List) Init(val any) *List {
|
||||
return Init(this, val)
|
||||
}
|
||||
|
||||
func Init(this *List, val any) *List {
|
||||
this.Value = val
|
||||
this.next = nil
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *List) Conj(val any) *List {
|
||||
return Conj(this, val)
|
||||
}
|
||||
|
||||
func Conj(this *List, val any) *List {
|
||||
new_head := New(val)
|
||||
new_head.next = this
|
||||
return new_head
|
||||
}
|
||||
|
||||
func Rest(this *List) *List {
|
||||
if this == nil {
|
||||
return nil
|
||||
}
|
||||
return this.next
|
||||
}
|
||||
|
||||
func (this *List) Rest() *List {
|
||||
return Rest(this)
|
||||
}
|
||||
|
||||
func First(this *List) any {
|
||||
return this.Value
|
||||
}
|
||||
|
||||
func (this *List) First() any {
|
||||
return First(this)
|
||||
}
|
||||
|
||||
func String(this *List) string {
|
||||
if this == nil {
|
||||
return "{}"
|
||||
}
|
||||
var sb strings.Builder
|
||||
sb.WriteRune('(')
|
||||
// Iterate and print elements
|
||||
for e := this; e != nil; e = Rest(e) {
|
||||
sb.WriteString(fmt.Sprint(e.Value))
|
||||
sb.WriteRune(' ')
|
||||
}
|
||||
return sb.String()[:sb.Len()-1] + ")"
|
||||
}
|
||||
|
||||
func (this *List) String() string {
|
||||
return String(this)
|
||||
}
|
||||
31
main.go
Normal file
31
main.go
Normal file
@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mal-go/hash_map"
|
||||
"mal-go/keyword"
|
||||
"mal-go/list"
|
||||
"mal-go/symbol"
|
||||
"mal-go/vector"
|
||||
)
|
||||
|
||||
func main() {
|
||||
myList := list.New(5)
|
||||
myList = myList.Conj(6)
|
||||
plus := symbol.Intern("clojure.core", "+")
|
||||
myList = myList.Conj(plus)
|
||||
fmt.Println(myList)
|
||||
|
||||
baz := keyword.Intern("baz")
|
||||
myMap := hash_map.New()
|
||||
myMap = myMap.Conj("foo", "bar")
|
||||
myMap = myMap.Conj(baz, 42)
|
||||
myMap = myMap.Conj("fizz", "buzz")
|
||||
fmt.Println(myMap)
|
||||
|
||||
myVec := vector.New()
|
||||
myVec = myVec.Conj(plus)
|
||||
myVec = myVec.Conj(1)
|
||||
myVec = myVec.Conj(2)
|
||||
fmt.Println(myVec)
|
||||
}
|
||||
36
symbol/symbol.go
Normal file
36
symbol/symbol.go
Normal file
@ -0,0 +1,36 @@
|
||||
package symbol
|
||||
|
||||
var intern_map map[string]*Symbol
|
||||
|
||||
type Symbol struct {
|
||||
ns string
|
||||
symbol string
|
||||
}
|
||||
|
||||
func Intern(ns string, symbol string) *Symbol {
|
||||
combined_str := ns + "/" + symbol
|
||||
existingSymbol, ok := intern_map[combined_str]
|
||||
if ok {
|
||||
return existingSymbol
|
||||
} else {
|
||||
newSymbol := new(Symbol)
|
||||
newSymbol.ns = ns
|
||||
newSymbol.symbol = symbol
|
||||
if intern_map == nil {
|
||||
intern_map = make(map[string]*Symbol)
|
||||
}
|
||||
intern_map[combined_str] = newSymbol
|
||||
return newSymbol
|
||||
}
|
||||
}
|
||||
|
||||
func String(this *Symbol) string {
|
||||
if this.ns == "" {
|
||||
return this.symbol
|
||||
}
|
||||
return this.ns + "/" + this.symbol
|
||||
}
|
||||
|
||||
func (this *Symbol) String() string {
|
||||
return String(this)
|
||||
}
|
||||
12
utils/utils.go
Normal file
12
utils/utils.go
Normal file
@ -0,0 +1,12 @@
|
||||
package utils
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Stringify(value any) string {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
return fmt.Sprintf("\"%s\"", value)
|
||||
default:
|
||||
return fmt.Sprint(value)
|
||||
}
|
||||
}
|
||||
51
vector/vector.go
Normal file
51
vector/vector.go
Normal file
@ -0,0 +1,51 @@
|
||||
package vector
|
||||
|
||||
import (
|
||||
"mal-go/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TODO: replace COW with proper HashArrayMappedTrie impelmentation of PersistentVector
|
||||
|
||||
type Vector struct {
|
||||
_slice []any
|
||||
}
|
||||
|
||||
func New() *Vector {
|
||||
return new(Vector).Init()
|
||||
}
|
||||
|
||||
func (this *Vector) Init() *Vector {
|
||||
this._slice = make([]any, 0)
|
||||
return this
|
||||
}
|
||||
|
||||
func Conj(this *Vector, data any) *Vector {
|
||||
newVec := New()
|
||||
for _, el := range this._slice {
|
||||
newVec._slice = append(newVec._slice, el)
|
||||
}
|
||||
newVec._slice = append(newVec._slice, data)
|
||||
return newVec
|
||||
}
|
||||
|
||||
func (this *Vector) Conj(data any) *Vector {
|
||||
return Conj(this, data)
|
||||
}
|
||||
|
||||
func String(this *Vector) string {
|
||||
if this == nil {
|
||||
return "[]"
|
||||
}
|
||||
var sb strings.Builder
|
||||
sb.WriteRune('[')
|
||||
for _, el := range this._slice {
|
||||
sb.WriteString(utils.Stringify(el))
|
||||
sb.WriteRune(' ')
|
||||
}
|
||||
return sb.String()[:sb.Len()-1] + "]"
|
||||
}
|
||||
|
||||
func (this *Vector) String() string {
|
||||
return String(this)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user