package bot import ( "fmt" "jinx/pkg/discord/events" "jinx/pkg/lang/compiler" "jinx/pkg/lang/modules" "jinx/pkg/lang/parser" "jinx/pkg/lang/scanner" "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, "lang": langCmd, } ) 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") return err } output := &chatOutput{ logger: b.logger, client: b.client, channel: msg.ChannelID, } vm := vm.New(modules.NewUnknownModule(&bc), output) b.logger.Info().Msgf("executing vm bytecode from user %s...", msg.Author.Username) if err := vm.Run(); err != nil { return err } b.logger.Debug().Msg("executed code") return nil } func langCmd(b *Bot, content string, msg events.Message) error { src := strings.Split(content, "```")[1] scanner := scanner.New(strings.NewReader(src)) tokens, err := scanner.Scan() if err != nil { return err } parser := parser.New(tokens) program, err := parser.Parse() if err != nil { return err } comp := compiler.New("chat program", msg.Author.Username, program) module, err := comp.Compile() if err != nil { b.logger.Error().Err(err).Msg("error compiling code") return err } b.client.SendMessage(msg.ChannelID, "successfully compiled code") decomp := text.NewDecompiler(*module.Code(), false) decompRes := decomp.Decompile() b.client.SendMessage(msg.ChannelID, fmt.Sprintf("resulting decompiled bytecode:\n```\n%s\n```", decompRes)) output := &chatOutput{ logger: b.logger, client: b.client, channel: msg.ChannelID, } vm := vm.New(module, output) b.logger.Info().Msgf("executing code from user %s...", msg.Author.Username) b.client.SendMessage(msg.ChannelID, "executing code...") if err := vm.Run(); err != nil { return err } b.logger.Debug().Msg("executed code") return nil }