# . # &***** # dino: (********@ # ~ an ~ ***/ # ~ LDPL ~ @*** # ~ interpreter ~ &@ # ~ in ~ %**%% # ~ LDPL ~ &**(( # %%****** # (( ((&********** # (@******************** # /********************** # ***********************,.& # ***********************###### # (*** ****/**************@#%####, # @**& **** ****.****.****#######( # === DINO =========================================================== # The `dino` command line program. DATA: main.file is text main.command is text main.i is number main.x is number main.y is number main.z is number main.l is number main.char is text main.ext is text main.ext.o is text main.key is text main.akey is text main.tkey is text PROCEDURE: # --- HELPER SUB-PROCEDURES ------------------------------------------ # Puts the file extension of argv:1 into main.ext, all uppercase. # ex file.ldpl => "LDPL" # IN: main.ext # OUT: main.ext sub-procedure main.ext store 0 in main.i store length of main.ext in main.l store main.ext in main.ext.o store "" in main.ext while main.i is less than main.l do get character at main.i from main.ext.o in main.char if main.char is equal to "." then add 1 and main.i in main.i get character at main.i from main.ext.o in main.ext else if main.ext is not equal to "" then join main.ext and main.char in main.ext end if add 1 and main.i in main.i repeat store main.ext in upcase.word call upcase-word store upcase.word in main.ext end sub-procedure # Loads source code into c.Input from STDIN or the command line. # IN: argv # argc # OUT: c.Input sub-procedure main.load-input if main.file is equal to "-" then accept c.input until eof else load file main.file in c.Input end if end sub-procedure # --- DISPLAY VERSION ------------------------------------------------ # $ dino version sub-procedure main.version display "\e[0m🦖 dino " $DINO.VERSION " (" $DINO.BUILT ") 🦖\e[0m" crlf end sub-procedure # --- DISPLAY HELP --------------------------------------------------- # $ dino help sub-procedure main.help display "Usage: dino [path]" crlf display crlf display "Commands:" crlf display " " "run " " " "execute .ldpl, .dinoasm, or .dinocode file" crlf display " " "asm " " " "compile .ldpl file to dino assembly" crlf display " " "bytes" " " "compile .ldpl or .dinoasm file to dinocode bytecode" crlf display " " "dis " " " "disassemble .dinocode file to dino assembly" crlf display " " "lex " " " "lex .ldpl file and print tokens" crlf display " " "parse" " " "parse .ldpl file and print nodes" crlf display " " "help " " " "print help screen" crlf display crlf display " When no command is given, `run` is assumed." crlf display crlf display "Examples:" crlf display " $ dino spark.ldpl 1 3 7 12 22 31 # run file with args" crlf display " $ dino bytes gild.ldpl # print dino bytecode" crlf display " $ dino asm spacemines.ldpl # print dino assembly" crlf end sub-procedure # --- LEX FILE ------------------------------------------------------- # $ dino lex file.ldpl # IN: main.file sub-procedure main.lex call main.load-input call lexer.Run store 0 in main.i display "\e[1mtokens (\e[34m" c.Tokens* "\e[0;1m):\e[0m\n " while main.i is less than c.Tokens* do display "\e[36m<\e[33m" c.Tokens:main.i "\e[36m>" if c.Tokens:main.i is equal to tokens.NEWLINE then display crlf add main.i and 1 in main.x if main.x is less than c.Tokens* then display " " end if else if main.i is less than c.Tokens* then display "\e[0m, " end if incr main.i repeat display "\e[0m" end sub-procedure # --- PARSE FILE ----------------------------------------------------- # $ dino parse file.ldpl # IN: main.file sub-procedure main.parse call main.load-input call lexer.Run call parser.Run display "\e[1mvars (\e[34m" parser.vars* "\e[0;1m):\e[0m\n" store 0 in main.i while main.i is less than parser.vars* do display " \e[33m" main.i ". \e[0m" $TYPENAMES:parser.vars:parser.vars:main.i ": " parser.vars:main.i crlf incr main.i repeat display "\e[0m" store 0 in main.i display "\e[1mnodes (\e[34m" c.Nodes* "\e[0;1m):\e[0m\n" while main.i is less than c.Nodes* do display "\e[36m" c.Nodes:main.i "\e[0m" crlf store 0 in main.x while main.x is less than 16 do in main.key join main.i ":" main.x if c.Nodes:main.key is not equal to "" then join main.key and ":type" in main.tkey display " \e[33m" main.x ".\e[0m " store $TYPENAMES:c.Nodes:main.tkey in main.tkey if main.tkey is equal to "NML" then else if main.tkey is equal to "TXL" then else display "\e[0;1m<" main.tkey ">\e[0m " end if display c.Nodes:main.key crlf store 0 in main.y while main.y is less than 16 do in main.akey join main.key ":" main.y join main.akey and ":type" in main.tkey if c.Nodes:main.akey is not equal to "" then display " \e[35m" main.y ".\e[0m " store $TYPENAMES:c.Nodes:main.tkey in main.tkey if main.tkey is equal to "NML" then else if main.tkey is equal to "TXL" then else display "\e[0;1m<" main.tkey ">\e[0m " end if display c.Nodes:main.akey crlf end if incr main.y repeat end if incr main.x repeat incr main.i repeat end sub-procedure # --- RUN FILE ------------------------------------------------------- # $ dino run file.ldpl # IN: main.file sub-procedure main.run.ldpl call main.load-input if ERRORCODE is greater than 0 then display ERRORTEXT crlf exit end if call lexer.Run call parser.Run call generator.Run call asm.Compile call asm.To-dinocode store asm.Dinocode in loader.input call vm.Boot call loader.Run call cpu.Run end sub-procedure # $ dino run file.dinoasm # IN: main.file sub-procedure main.run.dinoasm call main.load-input store c.Input in c.Asm if ERRORCODE is greater than 0 then display ERRORTEXT crlf exit end if call asm.Compile call asm.To-dinocode store asm.Dinocode in loader.input call vm.Boot call loader.Run call cpu.Run end sub-procedure # $ dino run file.dinocode # IN: main.file sub-procedure main.run.dinocode call main.load-input store c.Input in loader.Input if ERRORCODE is greater than 0 then display errortext crlf exit end if call vm.Boot call loader.Run call cpu.Run end sub-procedure # $ dino run file # IN: main.file sub-procedure main.run store main.file in main.ext call main.ext if main.ext is equal to "LDPL" then call main.run.ldpl else if main.ext is equal to "LSC" then call main.run.ldpl else if main.ext is equal to "DINOASM" then call main.run.dinoasm else if main.ext is equal to "DINOCODE" then call main.run.dinocode else display "\e[1;31mBad file extension: \e[0m" main.ext crlf exit end if end sub-procedure # --- CONVERT TO ASSEMBLY -------------------------------------------- # $ dino asm file.ldpl # IN: main.file sub-procedure main.ldpl-to-asm call main.load-input if ERRORCODE is greater than 0 then display ERRORTEXT crlf exit end if call lexer.Run call parser.Run call generator.Run display c.Asm end sub-procedure # --- CONVERT TO BYTECODE -------------------------------------------- # $ dino bytes file.ldpl # IN: main.file sub-procedure main.bytes.ldpl call main.load-input if ERRORCODE is greater than 0 then display ERRORTEXT crlf exit end if call lexer.Run call parser.Run call generator.Run call asm.Compile call asm.Print end sub-procedure # $ dino bytes file.dinoasm # IN: main.file sub-procedure main.bytes.dinoasm call main.load-input store c.Input in c.Asm if ERRORCODE is greater than 0 then display ERRORTEXT crlf exit end if call asm.Compile call asm.Print end sub-procedure # $ dino bytes file # IN: main.file sub-procedure main.bytes store main.file in main.ext call main.ext if main.ext is equal to "LDPL" then call main.bytes.ldpl else if main.ext is equal to "LSC" then call main.run.ldpl else if main.ext is equal to "DINOASM" then call main.run.dinoasm else if main.ext is equal to "DINOCODE" then display "\e[1;31mError: \e[0malready bytecode" crlf else display "\e[1;31mBad file extension: \e[0m" main.ext crlf exit end if end sub-procedure # --- CONVERT BYTECODE TO ASSEMBLY ----------------------------------- # $ dino dis file.dinocode # IN: main.file sub-procedure main.bytecode-to-asm call main.load-input store c.Input in loader.Input call loader.Run call dis.Print end sub-procedure # --- MAIN PROGRAM ROUTINE ------------------------------------------- sub-procedure main store argv:0 in main.command store argv:1 in main.file if main.command is equal to "bytes" then call main.bytes else if main.command is equal to "run" then call main.run else if main.command is equal to "asm" then call main.ldpl-to-asm else if main.command is equal to "dis" then call main.bytecode-to-asm else if main.command is equal to "lex" then call main.lex else if main.command is equal to "parse" then call main.parse else if main.command is equal to "-v" then call main.version else if main.command is equal to "version" then call main.version else store main.command in main.ext store main.command in main.file if main.ext is equal to "-" then store "LDPL" in main.ext else call main.ext end if if main.ext is equal to "LDPL" then call main.run.ldpl else if main.ext is equal to "LSC" then call main.run.ldpl else if main.ext is equal to "DINOASM" then call main.run.dinoasm else if main.ext is equal to "DINOCODE" then call main.run.dinocode else call main.help end if end if end sub-procedure call main # boing boing boing # e-e . - . . - . . - . # (\_/)\ ' `. ,' `. ,' . # `-'\ `--.___, . . . . . # '\( ,_.-' # \\ " " a:f # ^'