11import os
22import subprocess
33import tempfile
4+ import readline # For history
45from rich .console import Console
56from rich .prompt import Prompt
67from rich .panel import Panel
7- from hacker_parser import parse_hacker_file # Changed from parser to hacker_parser
8+ from hacker_parser import parse_hacker_file
89
9- def run_repl (console , verbose = False ):
10- console .print (Panel ("Hacker Lang REPL - Type 'exit' to quit" , title = "REPL" , style = "bold magenta" ))
11- console .print ("Supports: // (deps), # (libs), @ (vars), = (loop), ? (if), & (bg), > (cmd), [ ] (config), ! (comment)" )
10+ HISTORY_FILE = os .path .expanduser ("~/.hacker_repl_history" )
1211
12+ def load_history ():
13+ if os .path .exists (HISTORY_FILE ):
14+ with open (HISTORY_FILE , 'r' ) as f :
15+ for line in f :
16+ readline .add_history (line .strip ())
17+
18+ def save_history (line ):
19+ with open (HISTORY_FILE , 'a' ) as f :
20+ f .write (line + '\n ' )
21+
22+ def run_repl (verbose = False ):
23+ console = Console ()
24+ console .print (Panel ("Hacker Lang REPL v0.1 - Enhanced Interactive Mode\n Type 'exit' to quit, 'help' for commands, 'clear' to reset" , title = "REPL Welcome" , border_style = "bold magenta" ))
25+ console .print ("Supported: //deps, #libs, @vars, =loops, ?ifs, &bg, >cmds, [config], !comments" )
26+ load_history ()
1327 lines = []
1428 in_config = False
15-
1629 while True :
1730 try :
18- prompt = "CONFIG> " if in_config else "> "
31+ prompt = "CONFIG> " if in_config else "hacker > "
1932 line = Prompt .ask (prompt , console = console ).strip ()
20-
33+ if not line :
34+ continue
35+ save_history (line )
2136 if line .lower () == 'exit' :
2237 break
23-
38+ elif line .lower () == 'help' :
39+ console .print (Panel ("REPL Commands:\n - exit: Quit REPL\n - help: This menu\n - clear: Reset session\n - verbose: Toggle verbose" , border_style = "bold cyan" ))
40+ continue
41+ elif line .lower () == 'clear' :
42+ lines = []
43+ in_config = False
44+ console .print ("[bold yellow]Session cleared![/bold yellow]" )
45+ continue
46+ elif line .lower () == 'verbose' :
47+ verbose = not verbose
48+ console .print (f"[bold blue]Verbose mode: { 'ON' if verbose else 'OFF' } [/bold blue]" )
49+ continue
2450 if line == '[' :
2551 in_config = True
2652 lines .append (line )
2753 continue
2854 if line == ']' :
2955 if not in_config :
30- console .print ("[bold red]Error: Closing ] without [ [/bold red]" )
56+ console .print ("[bold red]Error: Unmatched ']' [/bold red]" )
3157 continue
3258 in_config = False
3359 lines .append (line )
3460 continue
35-
3661 lines .append (line )
37-
3862 if not in_config and line and not line .startswith ('!' ):
3963 with tempfile .NamedTemporaryFile (mode = 'w+' , suffix = '.hacker' , delete = False ) as f :
4064 f .write ('\n ' .join (lines ) + '\n ' )
4165 temp_path = f .name
42-
43- deps , libs , vars_dict , cmds , includes , errors = parse_hacker_file (temp_path , verbose , console )
66+ deps , libs , vars_dict , cmds , includes , binaries , errors , config = parse_hacker_file (temp_path , verbose , console )
4467 os .unlink (temp_path )
45-
4668 if errors :
47- console .print (Panel ("\n " .join (errors ), title = "REPL Errors" , style = "bold red" ))
69+ console .print (Panel ("\n " .join (errors ), title = "REPL Errors" , border_style = "bold red" ))
4870 continue
49-
5071 with tempfile .NamedTemporaryFile (mode = 'w+' , suffix = '.sh' , delete = False ) as f :
5172 f .write ('#!/bin/bash\n set -e\n ' )
5273 for k , v in vars_dict .items ():
@@ -55,29 +76,28 @@ def run_repl(console, verbose=False):
5576 if dep != "sudo" :
5677 f .write (f"command -v { dep } || (sudo apt update && sudo apt install -y { dep } )\n " )
5778 for inc in includes :
58- lib_path = os .path .join (os . path . expanduser ( "~/.hackeros/hacker-lang" ) , "libs" , inc , "main.hacker" ) # Updated path
79+ lib_path = os .path .join (HACKER_DIR , "libs" , inc , "main.hacker" )
5980 if os .path .exists (lib_path ):
6081 f .write (f"# include { inc } \n " )
6182 with open (lib_path ) as lf :
6283 f .write (lf .read () + "\n " )
6384 for cmd in cmds :
6485 f .write (cmd + "\n " )
86+ for bin_path in binaries :
87+ f .write (f"{ bin_path } \n " )
6588 sh_path = f .name
66-
6789 os .chmod (sh_path , 0o755 )
6890 try :
6991 env = os .environ .copy ()
7092 env .update (vars_dict )
7193 output = subprocess .check_output (['bash' , sh_path ], env = env , text = True , stderr = subprocess .STDOUT )
7294 if output .strip ():
73- console .print (Panel (output .strip (), title = "Output" , style = "bold green" ))
95+ console .print (Panel (output .strip (), title = "REPL Output" , border_style = "bold green" ))
7496 except subprocess .CalledProcessError as e :
75- console .print (Panel (e .output .strip (), title = "Error" , style = "bold red" ))
97+ console .print (Panel (e .output .strip (), title = "REPL Error" , border_style = "bold red" ))
7698 finally :
7799 os .unlink (sh_path )
78-
79100 except KeyboardInterrupt :
80- console .print ("\n [bold yellow]Use 'exit' to quit[/bold yellow]" )
81-
82- console .print ("[bold green]REPL exited[/bold green]" )
101+ console .print ("\n [bold yellow]Interrupt detected. Use 'exit' to quit.[/bold yellow]" )
102+ console .print ("[bold green]REPL session ended.[/bold green]" )
83103 return True
0 commit comments