From 399cfc35020f9bbf40d61dc8519a4282365ab579 Mon Sep 17 00:00:00 2001 From: Syntax Date: Wed, 23 Jul 2025 02:31:18 -0300 Subject: [PATCH] Primeiro commit --- .../geany-reddust/filetypes.reddust.conf | 19 ++ highlighting/vim-reddust/reddust.vim | 16 ++ highlighting/vscode-reddust/icon.png | Bin 0 -> 2488 bytes .../language-configuration.json | 5 + highlighting/vscode-reddust/package.json | 28 +++ .../vscode-reddust/reddust-1.0.0.vsix | Bin 0 -> 1932 bytes .../vscode-reddust/reddust.tmLanguage.json | 19 ++ icon/reddust.png | Bin 0 -> 971 bytes redd-install.sh | 76 ++++++ redd-uninstall.sh | 28 +++ reddust1 | 216 ++++++++++++++++++ 11 files changed, 407 insertions(+) create mode 100644 highlighting/geany-reddust/filetypes.reddust.conf create mode 100644 highlighting/vim-reddust/reddust.vim create mode 100644 highlighting/vscode-reddust/icon.png create mode 100644 highlighting/vscode-reddust/language-configuration.json create mode 100644 highlighting/vscode-reddust/package.json create mode 100644 highlighting/vscode-reddust/reddust-1.0.0.vsix create mode 100644 highlighting/vscode-reddust/reddust.tmLanguage.json create mode 100644 icon/reddust.png create mode 100644 redd-install.sh create mode 100644 redd-uninstall.sh create mode 100755 reddust1 diff --git a/highlighting/geany-reddust/filetypes.reddust.conf b/highlighting/geany-reddust/filetypes.reddust.conf new file mode 100644 index 0000000..d2370ce --- /dev/null +++ b/highlighting/geany-reddust/filetypes.reddust.conf @@ -0,0 +1,19 @@ +[styling] +default=0x000000;#FFFFFF;false;false +keyword=0x0000FF;#FFFFFF;true;false +comment=0x008000;#FFFFFF;false;true +number=0xFF0000;#FFFFFF;false;false + +[keywords] +# Palavras-chave são dígitos hex (0-9 e A-F), conforme seu tema VSCode, +# mas Geany keywords são palavras fixas, então colocaremos os dígitos + +keywords=0 1 2 3 4 5 6 7 8 9 A B C D E F + +[settings] +# Configurações para comentários +comment_single=// + +[options] +# Case insensitive keywords? Para Hex, deixamos case sensitive (false) +case_sensitive=true diff --git a/highlighting/vim-reddust/reddust.vim b/highlighting/vim-reddust/reddust.vim new file mode 100644 index 0000000..30cb189 --- /dev/null +++ b/highlighting/vim-reddust/reddust.vim @@ -0,0 +1,16 @@ +" Syntax file for RedDust +" Maintainer: Syntax Echonomics + +if exists("b:current_syntax") + finish +endif + +syntax match reddustKeyword /^\s*[0-9A-F]\ze;/ +syntax match reddustNumber /\v\<[0-9A-F]\>/ +syntax match reddustComment "//.*$" + +highlight def link reddustKeyword Keyword +highlight def link reddustNumber Number +highlight def link reddustComment Comment + +let b:current_syntax = "reddust" diff --git a/highlighting/vscode-reddust/icon.png b/highlighting/vscode-reddust/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..74ca187af95f5c3f67a6e37f13c73b58faaaed88 GIT binary patch literal 2488 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 GFb@D1A_+eL literal 0 HcmV?d00001 diff --git a/highlighting/vscode-reddust/reddust.tmLanguage.json b/highlighting/vscode-reddust/reddust.tmLanguage.json new file mode 100644 index 0000000..a198297 --- /dev/null +++ b/highlighting/vscode-reddust/reddust.tmLanguage.json @@ -0,0 +1,19 @@ +{ + "scopeName": "source.reddust", + "patterns": [ + + { + "name": "keyword.control.reddust", + "match": "^(\\s*[0-9A-F])(?=;)" + }, + + { + "name": "constant.numeric.reddust", + "match": "\\b[0-9A-F]\\b" + }, + { + "name": "comment.line.double-slash.reddust", + "match": "//.*$" + } + ] +} diff --git a/icon/reddust.png b/icon/reddust.png new file mode 100644 index 0000000000000000000000000000000000000000..124ab2e13ba7878580bddc2b1542d72a6d013fd1 GIT binary patch literal 971 zcmV;+12p`JP)85U*LIq=H}+k008~~0L=gZ=j-bK|NqVg z2H~Wn&I=3QkB{f+>fLyF@5aUNzrOCy&gbap>(|!&0s`A-XykHo_9P_elauP9q0b^B z&kzyk;o#VH#4-fd~=kQ)$`}Onv z`})^QOX=w8{{R3D;o(F8000bhQchEVfB2f0_U4JA(!8$V-4a3o00P5FL_t(o!`;{I za-uL42H?_){n!AKrU4=$f<_T6=xW=&|0~->P-_Vgb@tD`GtMDSc}&R(%H3TZ<7sGh z20k0cU3-kjq0<@5x_{{e9!!{d9eEeRFQW^%hp!`y@z*K1jy(EWiaD51MmK;#dnDit zAB>v-%Nh=h+W`3dXxs!?PMe?$Sn%aWz(Hz34e(Hep8;YqmF=Je@H!WX$L9c4wu1^7 zj|ys2%CHnN=d>+U?Vtd7yiKWX(|qgkb3oM&O#lOVx(uC!7-Z)=^RXA;Unt+~4nkTZk)u9QtnTc2J6pN{n3tf6_7abei@6O7g2u|(_hqX$nR8tj(Gq8002ovPDHLkV1m2V(*ytj literal 0 HcmV?d00001 diff --git a/redd-install.sh b/redd-install.sh new file mode 100644 index 0000000..b161eab --- /dev/null +++ b/redd-install.sh @@ -0,0 +1,76 @@ +#!/bin/bash +set -e + +INSTALL_DIR="/usr/local/bin" +ICON_DIR="/usr/share/icons/reddust" +MIME_DIR="/usr/share/mime/packages" +VSCODE_EXT_DIR="$HOME/.vscode/extensions/reddust-syntax" +GITHUB_RAW="https://raw.githubusercontent.com/SynthX7/reddust/main" + +echo "[INFO] Iniciando instalação do RedDust..." + +# 1. Verifica se Python 3 está instalado +if ! command -v python3 &> /dev/null; then + echo "[INFO] Python3 não encontrado. Instalando..." + if [ -f /etc/debian_version ]; then + sudo apt-get update && sudo apt-get install -y python3 + elif [ -f /etc/arch-release ]; then + sudo pacman -Sy --noconfirm python + else + echo "[ERRO] Não foi possível detectar a distribuição. Instale Python 3 manualmente." + exit 1 + fi +else + echo "[INFO] Python3 já está instalado." +fi + +# 2. Instala interpretador +echo "[INFO] Instalando interpretador RedDust..." +sudo curl -fsSL "$GITHUB_RAW/reddust" -o "$INSTALL_DIR/reddust" +sudo chmod +x "$INSTALL_DIR/reddust" + +# 3. Ícone +echo "[INFO] Instalando ícone..." +sudo mkdir -p "$ICON_DIR" +sudo curl -fsSL "$GITHUB_RAW/icon/reddust.png" -o "$ICON_DIR/icon.png" + +# 4. Configuração MIME +echo "[INFO] Configurando MIME..." +sudo tee "$MIME_DIR/reddust.xml" > /dev/null < + + + RedDust Source Code + + + + +EOF +sudo update-mime-database /usr/share/mime +sudo update-icon-caches /usr/share/icons/* + +# 5. VSCode Syntax +echo "[INFO] Instalando suporte para VSCode..." +mkdir -p "$VSCODE_EXT_DIR" +curl -fsSL "$GITHUB_RAW/highlighting/vscode-reddust/package.json" -o "$VSCODE_EXT_DIR/package.json" +curl -fsSL "$GITHUB_RAW/highlighting/vscode-reddust/reddust.tmLanguage.json" -o "$VSCODE_EXT_DIR/reddust.tmLanguage.json" +curl -fsSL "$GITHUB_RAW/highlighting/vscode-reddust/language-configuration.json" -o "$VSCODE_EXT_DIR/language-configuration.json" +curl -fsSL "$GITHUB_RAW/highlighting/vscode-reddust/icon.png" -o "$VSCODE_EXT_DIR/icon.png" + +# 6. Geany Syntax +echo "[INFO] Instalando suporte para Geany..." +mkdir -p ~/.config/geany/filedefs +curl -fsSL "$GITHUB_RAW/highlighting/geany-reddust/filetypes.reddust.conf" -o ~/.config/geany/filedefs/filetypes.reddust.conf + +# 7. Vim Syntax +echo "[INFO] Instalando suporte para Vim..." +mkdir -p ~/.vim/syntax +curl -fsSL "$GITHUB_RAW/highlighting/vim-reddust/reddust.vim" -o ~/.vim/syntax/reddust.vim +grep -qxF 'au BufNewFile,BufRead *.redd set filetype=reddust' ~/.vimrc || echo 'au BufNewFile,BufRead *.redd set filetype=reddust' >> ~/.vimrc + +# Nano (opcional) +mkdir -p ~/.nano +grep -qxF 'include ~/.nano/reddust.nanorc' ~/.nanorc || echo '# Syntax RedDust\ninclude ~/.nano/reddust.nanorc' >> ~/.nanorc + +echo "[INFO] Instalação concluída! É recomendável reiniciar o sistema ou a sessão atual." +echo "✅ Use com: reddust arquivo.redd" diff --git a/redd-uninstall.sh b/redd-uninstall.sh new file mode 100644 index 0000000..a369f98 --- /dev/null +++ b/redd-uninstall.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e + +echo "[INFO] Removendo RedDust..." + +# Interpretador +sudo rm -f /usr/local/bin/reddust + +# Ícone e MIME +sudo rm -rf /usr/share/icons/reddust +sudo rm -f /usr/share/mime/packages/reddust.xml +sudo update-mime-database /usr/share/mime + +# VSCode +rm -rf ~/.vscode/extensions/reddust-syntax + +# Geany +rm -f ~/.config/geany/filedefs/filetypes.reddust.conf + +# Vim +rm -f ~/.vim/syntax/reddust.vim +sed -i '/reddust/d' ~/.vimrc + +# Nano +sed -i '/reddust.nanorc/d' ~/.nanorc +rm -f ~/.nano/reddust.nanorc + +echo "[INFO] RedDust removido com sucesso!" diff --git a/reddust1 b/reddust1 new file mode 100755 index 0000000..015dbc4 --- /dev/null +++ b/reddust1 @@ -0,0 +1,216 @@ +#!/usr/bin/env python3 +import sys +import random +import time + +# Memória da máquina +memory = [0] * 256 # 256 endereços possíveis + + +def parse_line(line): + # Remove comentários após "//" + line = line.split('//')[0].strip() + if not line: + return None + + tokens = [t.strip() for t in line.split(';') if t.strip()] + + if len(tokens) != 4: + print(f"[ERRO] Linha inválida (esperado 4 valores): {line}") + return None + + try: + return [int(t, 16) for t in tokens] # HEX -> int + except ValueError: + print(f"[ERRO] Valores inválidos na linha: {line}") + return None + + +def to_hex(val): + return format(val, 'X') + + +def run_program(program, debug=False): + pc = 0 + while pc < len(program): + instr = program[pc] + cmd = format(instr[0], 'X') + + if debug: + hex_instr = [to_hex(x) for x in instr] + hex_mem = [to_hex(x) for x in memory[:16]] + print(f"[DEBUG] PC={to_hex(pc+1)}, CMD={hex_instr}, MEM[0..F]={hex_mem}") + + if cmd == "0": # HALT + print("[INFO] Programa finalizado.") + break + + elif cmd == "1": # INPUT + a, b = instr[1], instr[2] + if b != 0: + memory[a] = b + else: + print("[INFO] Waiting for input...") + try: + value = input(f"Digite valor HEX para mem[{to_hex(a)}]: ").strip() + memory[a] = int(value, 16) + except KeyboardInterrupt: + print("\n[INFO] Entrada cancelada pelo usuário (Ctrl+C).") + sys.exit(0) + except ValueError: + print("[ERRO] Valor inválido! Use HEX (ex.: A, F, 1F)") + return None + + elif cmd == "2": # OUTPUT + addr = instr[1] + print(f"[OUTPUT] {to_hex(memory[addr])}") + + elif cmd == "3": # ADD + a, b, c = instr[1], instr[2], instr[3] + memory[c] = memory[a] + memory[b] + + elif cmd == "4": # SUB + a, b, c = instr[1], instr[2], instr[3] + memory[c] = memory[a] - memory[b] + + elif cmd == "5": # DIV + a, b, c = instr[1], instr[2], instr[3] + memory[c] = memory[a] // memory[b] if memory[b] != 0 else 0 + + elif cmd == "6": # MUL + a, b, c = instr[1], instr[2], instr[3] + memory[c] = memory[a] * memory[b] + + elif cmd == "7": # COND JUMP + addr, val, target = instr[1], instr[2], instr[3] + if memory[addr] == val: + pc = target - 1 + continue + + elif cmd == "8": # JUMP + pc = instr[1] - 1 + continue + + elif cmd == "9": # CLEAR + addr = instr[1] + memory[addr] = 0 + + elif cmd == "A": # RANDOM + addr = instr[1] + memory[addr] = random.randint(0, 15) + + elif cmd == "B": # CMP GREATER + x, y, out = instr[1], instr[2], instr[3] + memory[out] = 1 if memory[x] > memory[y] else 0 + + elif cmd == "C": # CMP LESS + x, y, out = instr[1], instr[2], instr[3] + memory[out] = 1 if memory[x] < memory[y] else 0 + + elif cmd == "D": # MOVE + src, dst = instr[1], instr[2] + memory[dst] = memory[src] + + elif cmd == "E": # INC/DEC + addr, flag = instr[1], instr[2] + if flag == 1: + memory[addr] += 1 + elif flag == 0: + memory[addr] -= 1 + else: + print(f"[ERRO] Flag inválida: {to_hex(flag)}") + return None + + elif cmd == "F": # WAIT + delay = instr[1] + print(f"[INFO] Esperando {delay} segundos...") + time.sleep(delay) + + else: + print(f"[ERRO] Comando inválido: {cmd}") + return None + + pc += 1 + + +def repl(): + print("Modo REPL RedDust (digite 'exit' para sair)") + program = [] + line_num = 1 + while True: + try: + line = input(f"linha {line_num}> ").strip() + if line.lower() == "exit": + print("[INFO] Saindo do REPL e executando programa...") + break + instr = parse_line(line) + if instr: + program.append(instr) + line_num += 1 + except KeyboardInterrupt: + print("\n[INFO] Interrompido pelo usuário (Ctrl+C).") + sys.exit(0) + run_program(program) + + +def show_help(): + print(""" +RedDust Interpreter v3.1 +Uso: + reddust Executa um programa RedDust + reddust Inicia modo interativo (REPL) + reddust --debug Executa com debug (mostra memória) + reddust --version Mostra versão + reddust --help Exibe esta ajuda + +Formato do código: + Cada linha deve conter 4 valores HEX separados por ponto-e-vírgula (;) + Exemplo: + 1;A;0;0 // INPUT: pede valor para mem[A] + 2;A;0;0 // OUTPUT: mostra mem[A] + 0;0;0;0 // HALT +""") + + +def main(): + try: + if "--help" in sys.argv: + show_help() + sys.exit(0) + + if "--version" in sys.argv: + print("RedDust Interpreter v3.1 (HEX Mode)") + sys.exit(0) + + debug = "--debug" in sys.argv + + if len(sys.argv) == 1 or (len(sys.argv) == 2 and debug): + repl() + return + + filename = sys.argv[1] + if not filename.endswith(".redd"): + print("[ERRO] Arquivo deve ter extensão .redd") + sys.exit(1) + + try: + with open(filename, 'r') as f: + lines = f.readlines() + except FileNotFoundError: + print(f"[ERRO] Arquivo '{filename}' não encontrado.") + sys.exit(1) + + program = [] + for line in lines: + instr = parse_line(line) + if instr: + program.append(instr) + run_program(program, debug) + + except KeyboardInterrupt: + print("\n[INFO] Execução interrompida pelo usuário (Ctrl+C).") + sys.exit(0) + + +if __name__ == "__main__": + main()