mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-24 11:42:03 -08:00
1bb39eba87
TengoModifyMessage allows you to specify the location of a tengo (https://github.com/d5/tengo/) script. This script will receive every incoming message and can be used to modify the Username and the Text of that message. The script will have the following global variables: to modify: msgUsername and msgText to read: msgChannel and msgAccount The script is reloaded on every message, so you can modify the script on the fly. Example script can be found in https://github.com/42wim/matterbridge/tree/master/gateway/bench.tengo and https://github.com/42wim/matterbridge/tree/master/contrib/example.tengo The example below will check if the text contains blah and if so, it'll replace the text and the username of that message. text := import("text") if text.re_match("blah",msgText) { msgText="replaced by this" msgUsername="fakeuser" } More information about tengo on: https://github.com/d5/tengo/blob/master/docs/tutorial.md and https://github.com/d5/tengo/blob/master/docs/stdlib.md
134 lines
2.9 KiB
Go
134 lines
2.9 KiB
Go
package compiler
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/d5/tengo/compiler/ast"
|
|
"github.com/d5/tengo/compiler/token"
|
|
)
|
|
|
|
func (c *Compiler) compileAssign(node ast.Node, lhs, rhs []ast.Expr, op token.Token) error {
|
|
numLHS, numRHS := len(lhs), len(rhs)
|
|
if numLHS > 1 || numRHS > 1 {
|
|
return c.errorf(node, "tuple assignment not allowed")
|
|
}
|
|
|
|
// resolve and compile left-hand side
|
|
ident, selectors := resolveAssignLHS(lhs[0])
|
|
numSel := len(selectors)
|
|
|
|
if op == token.Define && numSel > 0 {
|
|
// using selector on new variable does not make sense
|
|
return c.errorf(node, "operator ':=' not allowed with selector")
|
|
}
|
|
|
|
symbol, depth, exists := c.symbolTable.Resolve(ident)
|
|
if op == token.Define {
|
|
if depth == 0 && exists {
|
|
return c.errorf(node, "'%s' redeclared in this block", ident)
|
|
}
|
|
|
|
symbol = c.symbolTable.Define(ident)
|
|
} else {
|
|
if !exists {
|
|
return c.errorf(node, "unresolved reference '%s'", ident)
|
|
}
|
|
}
|
|
|
|
// +=, -=, *=, /=
|
|
if op != token.Assign && op != token.Define {
|
|
if err := c.Compile(lhs[0]); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// compile RHSs
|
|
for _, expr := range rhs {
|
|
if err := c.Compile(expr); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
switch op {
|
|
case token.AddAssign:
|
|
c.emit(node, OpAdd)
|
|
case token.SubAssign:
|
|
c.emit(node, OpSub)
|
|
case token.MulAssign:
|
|
c.emit(node, OpMul)
|
|
case token.QuoAssign:
|
|
c.emit(node, OpDiv)
|
|
case token.RemAssign:
|
|
c.emit(node, OpRem)
|
|
case token.AndAssign:
|
|
c.emit(node, OpBAnd)
|
|
case token.OrAssign:
|
|
c.emit(node, OpBOr)
|
|
case token.AndNotAssign:
|
|
c.emit(node, OpBAndNot)
|
|
case token.XorAssign:
|
|
c.emit(node, OpBXor)
|
|
case token.ShlAssign:
|
|
c.emit(node, OpBShiftLeft)
|
|
case token.ShrAssign:
|
|
c.emit(node, OpBShiftRight)
|
|
}
|
|
|
|
// compile selector expressions (right to left)
|
|
for i := numSel - 1; i >= 0; i-- {
|
|
if err := c.Compile(selectors[i]); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
switch symbol.Scope {
|
|
case ScopeGlobal:
|
|
if numSel > 0 {
|
|
c.emit(node, OpSetSelGlobal, symbol.Index, numSel)
|
|
} else {
|
|
c.emit(node, OpSetGlobal, symbol.Index)
|
|
}
|
|
case ScopeLocal:
|
|
if numSel > 0 {
|
|
c.emit(node, OpSetSelLocal, symbol.Index, numSel)
|
|
} else {
|
|
if op == token.Define && !symbol.LocalAssigned {
|
|
c.emit(node, OpDefineLocal, symbol.Index)
|
|
} else {
|
|
c.emit(node, OpSetLocal, symbol.Index)
|
|
}
|
|
}
|
|
|
|
// mark the symbol as local-assigned
|
|
symbol.LocalAssigned = true
|
|
case ScopeFree:
|
|
if numSel > 0 {
|
|
c.emit(node, OpSetSelFree, symbol.Index, numSel)
|
|
} else {
|
|
c.emit(node, OpSetFree, symbol.Index)
|
|
}
|
|
default:
|
|
panic(fmt.Errorf("invalid assignment variable scope: %s", symbol.Scope))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func resolveAssignLHS(expr ast.Expr) (name string, selectors []ast.Expr) {
|
|
switch term := expr.(type) {
|
|
case *ast.SelectorExpr:
|
|
name, selectors = resolveAssignLHS(term.Expr)
|
|
selectors = append(selectors, term.Sel)
|
|
return
|
|
|
|
case *ast.IndexExpr:
|
|
name, selectors = resolveAssignLHS(term.Expr)
|
|
selectors = append(selectors, term.Index)
|
|
|
|
case *ast.Ident:
|
|
name = term.Name
|
|
}
|
|
|
|
return
|
|
}
|