aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/bot/bot.go35
-rw-r--r--pkg/bot/cmds.go40
-rw-r--r--pkg/lang/vm/vm.go4
3 files changed, 74 insertions, 5 deletions
diff --git a/pkg/bot/bot.go b/pkg/bot/bot.go
index abee7bc..81b5548 100644
--- a/pkg/bot/bot.go
+++ b/pkg/bot/bot.go
@@ -3,10 +3,13 @@ package bot
import (
"jinx/pkg/discord"
"jinx/pkg/discord/events"
+ "strings"
"github.com/rs/zerolog"
)
+const PREFIX = "!"
+
type Bot struct {
client *discord.Discord
logger *zerolog.Logger
@@ -28,11 +31,7 @@ func (b *Bot) Start() error {
msg := m.(events.Message)
b.logger.Debug().Msgf("message: %s", msg.Content)
- if msg.Content == "ping" {
- if err := b.client.SendMessage(msg.ChannelID, "pong"); err != nil {
- b.logger.Error().Err(err).Msg("error sending message")
- }
- }
+ b.onMessage(msg)
})
if err := b.client.Connect(); err != nil {
@@ -45,3 +44,29 @@ func (b *Bot) Start() error {
func (b *Bot) Stop() error {
return b.client.Disconnect()
}
+
+func (b *Bot) onMessage(msg events.Message) {
+ b.logger.Debug().Msgf("message: %s", msg.Content)
+
+ if strings.HasPrefix(msg.Content, PREFIX) {
+ cmd := strings.TrimPrefix(msg.Content, PREFIX)
+ cmd = strings.Fields(cmd)[0]
+
+ rest := strings.TrimPrefix(msg.Content, PREFIX+cmd)
+
+ b.onCommand(cmd, rest, msg)
+ }
+}
+
+func (b *Bot) onCommand(name string, rest string, msg events.Message) {
+ if cmd, ok := nameToCmd[name]; ok {
+ b.logger.Debug().Msg("executing command...")
+ if err := cmd(b, rest, msg); err != nil {
+ b.logger.Error().Err(err).Msg("error executing command")
+ b.client.SendMessage(msg.ChannelID, "error executing command")
+ }
+ } else {
+ b.logger.Debug().Msgf("unknown command: %s", name)
+ b.client.SendMessage(msg.ChannelID, "unknown command")
+ }
+}
diff --git a/pkg/bot/cmds.go b/pkg/bot/cmds.go
new file mode 100644
index 0000000..1dfb2cb
--- /dev/null
+++ b/pkg/bot/cmds.go
@@ -0,0 +1,40 @@
+package bot
+
+import (
+ "jinx/pkg/discord/events"
+ "jinx/pkg/lang/vm"
+ "jinx/pkg/lang/vm/text"
+ "strings"
+)
+
+type Cmd func(b *Bot, content string, msg events.Message) error
+
+var (
+ nameToCmd = map[string]Cmd{
+ "ping": pingCmd,
+ "vm": vmCmd,
+ }
+)
+
+func pingCmd(b *Bot, content string, msg events.Message) error {
+ return b.client.SendMessage(msg.ChannelID, "pong")
+}
+
+func vmCmd(b *Bot, content string, msg events.Message) error {
+ src := strings.Split(content, "```")[1]
+
+ comp := text.NewCompiler(strings.NewReader(src))
+ bc, err := comp.Compile()
+ if err != nil {
+ b.logger.Error().Err(err).Msg("error compiling code")
+ }
+
+ vm := vm.New(&bc)
+
+ vm.Run()
+ res := vm.GetResult()
+
+ b.logger.Debug().Msg("executed code")
+
+ return b.client.SendMessage(msg.ChannelID, res)
+}
diff --git a/pkg/lang/vm/vm.go b/pkg/lang/vm/vm.go
index a6e1fb8..74f9f46 100644
--- a/pkg/lang/vm/vm.go
+++ b/pkg/lang/vm/vm.go
@@ -19,6 +19,10 @@ func New(code *code.Code) *VM {
}
}
+func (vm *VM) GetResult() string {
+ return fmt.Sprintf("%v", vm.stack.Top().Pop().Data())
+}
+
func (vm *VM) Run() {
for vm.pc < vm.code.Len() {
op, advance := vm.code.GetOp(vm.pc)