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