diff --git a/src/compiler/Exec_phr.sig b/src/compiler/Exec_phr.sig index ca56e5f..567f6d6 100644 --- a/src/compiler/Exec_phr.sig +++ b/src/compiler/Exec_phr.sig @@ -1,5 +1,5 @@ val execToplevelPhrase: Asynt.Dec -> unit; val quietdec : bool ref - +val hashbang : bool ref diff --git a/src/compiler/Exec_phr.sml b/src/compiler/Exec_phr.sml index 583ef02..8998a70 100644 --- a/src/compiler/Exec_phr.sml +++ b/src/compiler/Exec_phr.sml @@ -8,6 +8,10 @@ open Symtable Rtvals Load_phr; val quietdec = ref false ; +(* Is enabled if running with -hashbang arg: *) + +val hashbang = ref false ; + (* Executing a top-level declaration. *) local diff --git a/src/compiler/Lexer.lex b/src/compiler/Lexer.lex index 972cf74..e84f5c9 100644 --- a/src/compiler/Lexer.lex +++ b/src/compiler/Lexer.lex @@ -9,11 +9,11 @@ datatype lexingMode = NORMALlm | QUOTElm | ANTIQUOTElm + | HASHBANGlm val lexingMode = ref NORMALlm val parCount = Stack.new() : int Stack.t - fun resetLexerState() = ( lexingMode := NORMALlm; @@ -207,6 +207,10 @@ fun scanString scan lexbuf = setLexStartPos lexbuf (!savedLexemeStart - getLexAbsPos lexbuf) ) +(* enable support for Shebang/Hashbang *) +fun enableHashbang b = (if b + then lexingMode := HASHBANGlm + else lexingMode := NORMALlm; ()); } rule Token = parse @@ -221,12 +225,16 @@ rule Token = parse case !lexingMode of NORMALlm => QUOTER (get_stored_string()) + | HASHBANGlm => + QUOTER (get_stored_string()) | ANTIQUOTElm => QUOTEM (get_stored_string()) | QUOTElm => fatalError "Token") | ANTIQUOTElm => AntiQuotation lexbuf + | HASHBANGlm => + Hashbang lexbuf } and TokenN = parse @@ -461,6 +469,12 @@ and AntiQuotation = parse { skipString "ill-formed antiquotation" SkipQuotation lexbuf } +and Hashbang = parse + "#!" [^`\n` `\r`]* + { lexingMode := NORMALlm; Token lexbuf } + | "" + { lexingMode := NORMALlm; Token lexbuf } + ; diff --git a/src/compiler/Lexer.sig b/src/compiler/Lexer.sig index 6e58009..cec9db0 100644 --- a/src/compiler/Lexer.sig +++ b/src/compiler/Lexer.sig @@ -1,3 +1,6 @@ +(* Lexer.sig *) + +val enableHashbang : bool -> unit; val quotation : bool ref; val resetLexerState : unit -> unit; val Token : Lexing.lexbuf -> Parser.token; diff --git a/src/compiler/Maint.sml b/src/compiler/Maint.sml index 90868b1..4f49f08 100644 --- a/src/compiler/Maint.sml +++ b/src/compiler/Maint.sml @@ -3,6 +3,7 @@ open List BasicIO Nonstdio; open Miscsys Memory Fnlib Config Mixture Location Units Smlperv Rtvals Smltop; open Types (* cvr *); +open Lexer (*to set hashbang*); val initialFiles = ref ([] : string list); (* Initial loop *) @@ -72,6 +73,13 @@ fun set_value_polymorphism b _ = fun set_quietdec b _ = Exec_phr.quietdec := b; +fun set_hashbang b _ = + let in + Lexer.enableHashbang b; + Exec_phr.quietdec := b; + Exec_phr.hashbang := b + end; + fun add_include d = load_path := !load_path @ [d]; @@ -117,6 +125,8 @@ fun main () = ("-perv", Arg.String perv_set), ("-imptypes", Arg.Unit (set_value_polymorphism false)), ("-valuepoly", Arg.Unit (set_value_polymorphism true)), + ("-hashbang", Arg.Unit (set_hashbang true)), + ("-s", Arg.Unit (set_hashbang true)), ("-quietdec", Arg.Unit (set_quietdec true)), ("-msgstyle", Arg.String set_msgstyle), ("-m", Arg.String set_msgstyle), @@ -148,7 +158,8 @@ fun main () = resetTypes(); Miscsys.catch_interrupt true; input_lexbuf := Compiler.createLexerStream std_in; - (initial_loop() handle EndOfFile => ()); + (initial_loop() handle EndOfFile => + if !Exec_phr.hashbang then BasicIO.exit 0 else ()); main_loop() end handle diff --git a/src/launch/mosml.tpl b/src/launch/mosml.tpl index e13c5aa..2afc72d 100755 --- a/src/launch/mosml.tpl +++ b/src/launch/mosml.tpl @@ -24,6 +24,9 @@ while : ; do -quietdec) options="$options -quietdec" ;; + -s|-hashbang) + options="$options -hashbang" + ;; -valuepoly) options="$options -valuepoly" ;;