Skip to content

Commit

Permalink
Modwords - fist support for modwords, change to setwords (#210)
Browse files Browse the repository at this point in the history
* changing Rye shell to basic ansi colors, so it themable in terminals and works in emacs ansi-term

* added testing for failures in various do functions, ssh sever basics

* new funcs like nl and pink, ssh integration and example, errors tests starting

* ryel tools, embed_main flag, small fixes all around

* adding support for modwords and lmodwords , also partially opcpaths and pipecpaths

* improved modword with left options, added support for opcpath and pipecpath
  • Loading branch information
refaktor authored May 14, 2024
1 parent 527dfea commit 48009d9
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 15 deletions.
26 changes: 24 additions & 2 deletions env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,30 @@ func (e *RyeCtx) Get2(word int) (Object, bool, *RyeCtx) {
}

func (e *RyeCtx) Set(word int, val Object) Object {
e.state[word] = val
return val
if _, exists := e.state[word]; exists {
return NewError("Can't set already set word, try using modword")
} else {
e.state[word] = val
return val
}
}

func (e *RyeCtx) Unset(word int) Object {
if _, exists := e.state[word]; !exists {
return NewError("Can't unset non-existing word in this context")
} else {
delete(e.state, word)
return NewInteger(1)
}
}

func (e *RyeCtx) Mod(word int, val Object) Object {
if _, exists := e.state[word]; exists {
e.state[word] = val
return val
} else {
return NewError("Can't mod an unset word, try using setword")
}
}

type ProgramState struct {
Expand Down
4 changes: 4 additions & 0 deletions env/idxs.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ var NativeTypes = [...]string{ // Todo change to BuiltinTypes
"SpreadsheetRowType",
"Decimal",
"Vector",
"OpCPath",
"PipeCPath",
"Modword",
"LModword",
}

func (e *Idxs) IndexWord(w string) int {
Expand Down
101 changes: 99 additions & 2 deletions env/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const (
SpreadsheetRowType Type = 33
DecimalType Type = 34
VectorType Type = 35
OpCPathType Type = 36
PipeCPathType Type = 37
ModwordType Type = 38
LModwordType Type = 39
)

// after adding new type here, also add string to idxs.go
Expand Down Expand Up @@ -601,6 +605,96 @@ func (i LSetword) Dump(e Idxs) string {
return ":" + e.GetWord(i.Index)
}

//
// MODWORD
//

type Modword struct {
Index int
}

func NewModword(index int) *Modword {
nat := Modword{index}
return &nat
}

func (i Modword) Type() Type {
return ModwordType
}

func (i Modword) Inspect(e Idxs) string {
return "[Modword: " + e.GetWord(i.Index) + "]"
}

func (b Modword) Print(e Idxs) string {
return e.GetWord(b.Index) + ":"
}

func (i Modword) Trace(msg string) {
fmt.Print(msg + "(Modword): ")
fmt.Println(i.Index)
}

func (i Modword) GetKind() int {
return int(ModwordType)
}

func (i Modword) Equal(o Object) bool {
if i.Type() != o.Type() {
return false
}
return i.Index == o.(Modword).Index
}

func (i Modword) Dump(e Idxs) string {
return e.GetWord(i.Index) + ":"
}

//
// LMODWORD
//

type LModword struct {
Index int
}

func NewLModword(index int) *LModword {
nat := LModword{index}
return &nat
}

func (i LModword) Type() Type {
return LModwordType
}

func (i LModword) Inspect(e Idxs) string {
return "[LModword: " + e.GetWord(i.Index) + "]"
}

func (b LModword) Print(e Idxs) string {
return ":" + e.GetWord(b.Index)
}

func (i LModword) Trace(msg string) {
fmt.Print(msg + "(lModword): ")
fmt.Println(i.Index)
}

func (i LModword) GetKind() int {
return int(LModwordType)
}

func (i LModword) Equal(o Object) bool {
if i.Type() != o.Type() {
return false
}
return i.Index == o.(LModword).Index
}

func (i LModword) Dump(e Idxs) string {
return ":" + e.GetWord(i.Index)
}

//
// OPWORD
//
Expand Down Expand Up @@ -1448,6 +1542,7 @@ func (i Argword) Dump(e Idxs) string {
//

type CPath struct {
Mode int // 0 Cpath, 1 OpCpath , 2 PipeCPath
Cnt int
Word1 Word
Word2 Word
Expand Down Expand Up @@ -1491,15 +1586,17 @@ func (i CPath) GetKind() int {
return int(CPathType)
}

func NewCPath2(w1 Word, w2 Word) *CPath {
func NewCPath2(mode int, w1 Word, w2 Word) *CPath {
var cp CPath
cp.Mode = mode
cp.Cnt = 2
cp.Word1 = w1
cp.Word2 = w2
return &cp
}
func NewCPath3(w1 Word, w2 Word, w3 Word) *CPath {
func NewCPath3(mode int, w1 Word, w2 Word, w3 Word) *CPath {
var cp CPath
cp.Mode = mode
cp.Cnt = 3
cp.Word1 = w1
cp.Word2 = w2
Expand Down
14 changes: 14 additions & 0 deletions evaldo/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,20 @@ var builtins = map[string]*env.Builtin{
},
},

"unset!": { // ***
Argsn: 1,
Doc: "Unset a word in current context",
Pure: false,
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch word := arg0.(type) {
case env.Word:
return ps.Ctx.Unset(word.Index)
default:
return MakeArgError(ps, 1, []env.Type{env.WordType}, "set")
}
},
},

"get_": { // *** find a name or decide on order of naming with generic words clashes with
Argsn: 1,
Doc: "Returns value of the word in context",
Expand Down
71 changes: 66 additions & 5 deletions evaldo/evaldo.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,32 @@ func MaybeEvalOpwordOnRight(nextObj env.Object, ps *env.ProgramState, limited bo
ps.Ser.Next()
ps = EvalWord(ps, opword.ToWord(), ps.Res, false, opword.Force > 0)
return MaybeEvalOpwordOnRight(ps.Ser.Peek(), ps, limited)
case env.CPath:
if opword.Mode == 1 {
ps.Ser.Next()
ps = EvalWord(ps, opword, ps.Res, false, false) // WWWWWWWWWWWWWWWWWWWWWWWWWWWW error interface converions
// when calling cpath
return MaybeEvalOpwordOnRight(ps.Ser.Peek(), ps, limited)
} else if opword.Mode == 2 {
if limited {
return ps
}
ps.Ser.Next()
ps = EvalWord(ps, opword, ps.Res, false, false) // TODO .. check opword force
if ps.ReturnFlag {
return ps //... not sure if we need this
}
// checkFlagsBi()
/*if ps.FailureFlag { // uncommented 202008017
ps.FailureFlag = false
ps.ErrorFlag = true
ps.ReturnFlag = true
return ps
}*/
return MaybeEvalOpwordOnRight(ps.Ser.Peek(), ps, limited)
} else {
ps.SkipFlag = false
}
case env.Pipeword:
if limited {
return ps
Expand All @@ -274,7 +300,25 @@ func MaybeEvalOpwordOnRight(nextObj env.Object, ps *env.ProgramState, limited bo
}
//ProcOpword(nextObj, es)
idx := opword.Index
ps.Ctx.Set(idx, ps.Res)
ps.Res = ps.Ctx.Set(idx, ps.Res)
if ps.Res.Type() == env.ErrorType {
ps.ErrorFlag = true
return ps
}
ps.Ser.Next()
ps.SkipFlag = false
return MaybeEvalOpwordOnRight(ps.Ser.Peek(), ps, limited)
case env.LModword:
if limited {
return ps
}
//ProcOpword(nextObj, es)
idx := opword.Index
ps.Res = ps.Ctx.Mod(idx, ps.Res)
if ps.Res.Type() == env.ErrorType {
ps.ErrorFlag = true
return ps
}
ps.Ser.Next()
ps.SkipFlag = false
return MaybeEvalOpwordOnRight(ps.Ser.Peek(), ps, limited)
Expand Down Expand Up @@ -329,6 +373,8 @@ func EvalExpressionConcrete(ps *env.ProgramState) *env.ProgramState {
return EvalGenword(ps, object.(env.Genword), nil, false)
case env.SetwordType:
return EvalSetword(ps, object.(env.Setword))
case env.ModwordType:
return EvalModword(ps, object.(env.Modword))
case env.GetwordType:
return EvalGetword(ps, object.(env.Getword), nil, false)
case env.CommaType:
Expand Down Expand Up @@ -360,7 +406,6 @@ func findWordValue(ps *env.ProgramState, word1 env.Object) (bool, env.Object, *e
case env.Opword:
object, found := ps.Ctx.Get(word.Index)
return found, object, nil

case env.CPath:
currCtx := ps.Ctx
i := 1
Expand Down Expand Up @@ -421,8 +466,9 @@ func EvalWord(ps *env.ProgramState, word env.Object, leftVal env.Object, toLeft
}
}
// fmt.Println(kind)
if leftVal != nil && ps.Ctx.Kind.Index != -1 { // don't use generic words if context kind is -1 --- TODO temporary solution to isolates, think about it more
object, found = ps.Gen.Get(kind, word.(env.Word).Index)
rword, ok := word.(env.Word)
if ok && leftVal != nil && ps.Ctx.Kind.Index != -1 { // don't use generic words if context kind is -1 --- TODO temporary solution to isolates, think about it more
object, found = ps.Gen.Get(kind, rword.Index)
}
}
if found {
Expand Down Expand Up @@ -495,7 +541,22 @@ func EvalSetword(ps *env.ProgramState, word env.Setword) *env.ProgramState {
// es1 := EvalExpression(es)
ps1, _ := EvalExpressionInj(ps, nil, false)
idx := word.Index
ps1.Ctx.Set(idx, ps1.Res)
ps1.Res = ps1.Ctx.Set(idx, ps1.Res)
if ps1.Res.Type() == env.ErrorType {
ps1.ErrorFlag = true
}
return ps1
}

// evaluates expression to the right and sets the result of it to a word in current context
func EvalModword(ps *env.ProgramState, word env.Modword) *env.ProgramState {
// es1 := EvalExpression(es)
ps1, _ := EvalExpressionInj(ps, nil, false)
idx := word.Index
ps1.Res = ps1.Ctx.Mod(idx, ps1.Res)
if ps1.Res.Type() == env.ErrorType {
ps1.ErrorFlag = true
}
return ps1
}

Expand Down
Loading

0 comments on commit 48009d9

Please sign in to comment.