diff options
| author | Matthew Hall <hallmatthew314@gmail.com> | 2023-02-22 22:23:35 +1300 |
|---|---|---|
| committer | Matthew Hall <hallmatthew314@gmail.com> | 2023-02-22 22:24:29 +1300 |
| commit | bad32a12573bf14968746ea9ad0f6c4f20b50cf1 (patch) | |
| tree | 26ce098f30f054b2f2a742d2c06b857951ea68db | |
| parent | 0bde837174fcb9c17cb3adbf6bc3c7407cab10df (diff) | |
Re-work program structure, MAIN entrypoint + only PROC definitions
| -rw-r--r-- | DSL.hs | 2 | ||||
| -rw-r--r-- | DSL/Interpretation.hs | 11 | ||||
| -rw-r--r-- | DSL/Parsing.hs | 14 | ||||
| -rw-r--r-- | DSL/Types.hs | 2 | ||||
| -rw-r--r-- | README.md | 98 | ||||
| -rw-r--r-- | examples/fizzbuzz.dumb | 27 |
6 files changed, 82 insertions, 72 deletions
@@ -1,6 +1,6 @@ module DSL where -import DSL.BaseParsers (parse) +import DSL.BaseParsers (parse) -- for testing import DSL.Parsing import DSL.Interpretation diff --git a/DSL/Interpretation.hs b/DSL/Interpretation.hs index 37165c3..d9c53bd 100644 --- a/DSL/Interpretation.hs +++ b/DSL/Interpretation.hs @@ -8,6 +8,9 @@ import DSL.Util import DSL.Intrinsics import DSL.StdLib (stdlib) +entrypoint :: ProcName +entrypoint = "MAIN" + newMachine :: Machine newMachine = Machine { ok=True, stack=[], pTable=M.empty } @@ -93,8 +96,10 @@ evalBlocks (BLinear b:bs) m = applyLinear m b >>= evalBlocks bs evalBlocks (BIf c t f:bs) m = applyIf c t f m >>= evalBlocks bs evalBlocks (BWhile c b:bs) m = applyWhile c b m >>= evalBlocks bs -interpret :: (ProcTable, Program) -> IO () -interpret (t, p) = case mergeProcTables stdlib t of - Just t' -> () <$ evalBlocks p newMachine{ pTable=t' } +interpret :: ProcTable -> IO () +interpret t = case mergeProcTables stdlib t of Nothing -> putStrLn "Failed to include stdlib, duplicate proc definition?" + Just t' -> case M.lookup entrypoint t' of + Nothing -> putStrLn "No MAIN proc defined, aborting." + Just b -> () <$ evalBlocks b newMachine{ pTable=t' } diff --git a/DSL/Parsing.hs b/DSL/Parsing.hs index 72d6b23..d4d1253 100644 --- a/DSL/Parsing.hs +++ b/DSL/Parsing.hs @@ -191,16 +191,8 @@ blockP = firstOf [ whileP , linearP ] -programP :: DSLParser ([ProcSpec], Program) -programP = phrase $ procs `plus` code +stringToProgram :: String -> Maybe ProcTable +stringToProgram = (>>=buildProcTable . snd) . parse (tokenizer `chain` program) where - procs = mult procP - code = mult1 blockP - -stringToProgram :: String -> Maybe (ProcTable, Program) -stringToProgram = (>>=(f . snd)) . parse (tokenizer `chain` programP) - where - f (ps, b) = case buildProcTable ps of - Nothing -> Nothing - Just t -> Just (t, b) + program = phrase $ mult procP diff --git a/DSL/Types.hs b/DSL/Types.hs index 7467bfd..aa1fb22 100644 --- a/DSL/Types.hs +++ b/DSL/Types.hs @@ -69,8 +69,6 @@ type ProcSpec = (ProcName, [Block]) type ProcTable = Map ProcName [Block] -type Program = [Block] - data Machine = Machine { ok :: Bool , stack :: Stack , pTable :: ProcTable @@ -13,14 +13,15 @@ God help you if you want to use this for anything. ### Procedures -Custom procedures can be created before the main body of the program: +Code is separated into procedures. A program must define a procedure named `MAIN` to serve as the entrypoint. ``` PROC is-even? 2 OVER % 0 == END -4 is-even? . '''true''' -5 is-even? . '''false''' -PROC illegal "this is an error" . END ''' not allowed, defined after body program body ''' +PROC MAIN + 4 is-even? . '''true''' + 5 is-even? . '''false''' +END ``` ### Postfix/Reverse Polish notation @@ -28,24 +29,25 @@ PROC illegal "this is an error" . END ''' not allowed, defined after body progra Procedures are invoked by pushing its arguments to the stack in reverse order and then calling the procedure: ``` -''' compute 2+1 and print the result (3) ''' -1 2 + . - -''' compute 2-1 and print the result (1) ''' -1 2 - . - -''' compute 1-2 and print the result (-1) ''' -2 1 - . - -''' test if 5 is greater than 6 and print the result (false) ''' -6 5 > . - -''' compute 2+3, test if 3 is less than the sum, and print the result ''' -3 2 + 3 < . - -''' concatenate two strings and print the result ''' -" but backwards" "it's like LISP" ++ . - +PROC + ''' compute 2+1 and print the result (3) ''' + 1 2 + . + + ''' compute 2-1 and print the result (1) ''' + 1 2 - . + + ''' compute 1-2 and print the result (-1) ''' + 2 1 - . + + ''' test if 5 is greater than 6 and print the result (false) ''' + 6 5 > . + + ''' compute 2+3, test if 3 is less than the sum, and print the result ''' + 3 2 + 3 < . + + ''' concatenate two strings and print the result ''' + " but backwards" "it's like LISP" ++ . +END ``` ### Comments @@ -53,14 +55,16 @@ Procedures are invoked by pushing its arguments to the stack in reverse order an Comments are multi-line only and are opened and closed with three single-quotes: ``` -IF 2 9 % 0 == DO - ''' TODO: come up with a better message to print - maybe something to do with the mod result being 0? ''' - "true branch" -ELSE - ''' i feel like we could mention that the number is odd? or something? ''' - "false branch" -END . +PROC MAIN + IF 2 9 % 0 == DO + ''' TODO: come up with a better message to print + maybe something to do with the mod result being 0? ''' + "true branch" + ELSE + ''' i feel like we could mention that the number is odd? or something? ''' + "false branch" + END . +END ``` ### Control-flow @@ -68,14 +72,16 @@ END . DSL currently has IF/ELIF/ELSE blocks and WHILE loops: ``` -IF get-some-number 0 == DO - "the number is zero" . -ELIF get-some-number 1 == DO - "the number is one" . -ELIF get-some-number 2 == DO - "the number is two" . -ELSE - "this number has yet to be discovered by science" . +PROC MAIN + IF get-some-number 0 == DO + "the number is zero" . + ELIF get-some-number 1 == DO + "the number is one" . + ELIF get-some-number 2 == DO + "the number is two" . + ELSE + "this number has yet to be discovered by science" . + END END ``` @@ -83,15 +89,23 @@ END Most characters typically thought-of as 'special' have no special syntactic meaning in DSL. Some exceptions include: +* Sequences of characters that would be parsed as data literals * Double-quotes, which start and end string literals * Three single-quotes in a row, which start and end comment blocks * Other special character sequences already reserved as intrinsic / proc names ``` -''' this is okay ''' -PROC $(*^$%*&#$%# "this is a string that was just printed" . END - -''' this isn't ''' +''' these are okay ''' +PROC foo "this proc has a valid name" . END +PROC +foo- "this proc has a valid name" . END +PROC +fo8o- "this proc has a valid name" . END +PROC $(*^$%*&#$%#]} "this proc has a valid name" . END + +''' these aren't ''' +PROC true "this is a parser error" . END +PROC 123 "this is a parser error" . END +PROC "foo" "this is a parser error" . END PROC "foo "this is a parser error" . END +PROC '''foo''' "this is a parser error" . END ``` diff --git a/examples/fizzbuzz.dumb b/examples/fizzbuzz.dumb index 2ba6033..f9aa648 100644 --- a/examples/fizzbuzz.dumb +++ b/examples/fizzbuzz.dumb @@ -1,14 +1,15 @@ -''' bottom of the stack is the incrementing value, starts at 1 ''' -1 -''' while the incrementing value is <= 100 ''' -WHILE 100 OVER <= DO - ''' push string "Buzz" if inc. is divisible by 5, else an empty string ''' - 5 OVER % IF 0 == DO "Buzz" ELSE "" END - ''' push string "Fizz" if inc. is divisible by 3, else an empty string ''' - OVER 3 SWAP % IF 0 == DO "Fizz" ELSE "" END - ''' concat the two strings and copy the inc., if the string is empty, swap them ''' - ++ OVER SWAP IF DUP "" == DO SWAP END - ''' print the top of the stack, drop the next item, add 1 to inc. ''' - . DROP 1 + +PROC MAIN + ''' bottom of the stack is the incrementing value, starts at 1 ''' + 1 + ''' while the incrementing value is <= 100 ''' + WHILE 100 OVER <= DO + ''' push string "Buzz" if inc. is divisible by 5, else an empty string ''' + 5 OVER % IF 0 == DO "Buzz" ELSE "" END + ''' push string "Fizz" if inc. is divisible by 3, else an empty string ''' + OVER 3 SWAP % IF 0 == DO "Fizz" ELSE "" END + ''' concat the two strings and copy the inc., if the string is empty, swap them ''' + ++ OVER SWAP IF DUP "" == DO SWAP END + ''' print the top of the stack, drop the next item, add 1 to inc. ''' + . DROP 1 + + END END - |
