1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2025-02-09 16:31:42 +00:00

Initial values for reserved tables; checks length is right.

This commit is contained in:
Cat's Eye Technologies 2014-04-12 13:38:11 +01:00
parent f9d0c8173d
commit 7a3b3b1b25
7 changed files with 124 additions and 25 deletions

View File

@ -155,6 +155,11 @@ For more information, see the docs (which are written in the form of
Falderal literate test suites. If you have Falderal installed, you can run
the tests with `./test.sh`.)
* [Checking](https://github.com/catseye/SixtyPical/blob/master/doc/Checking.markdown)
* [Analyzing](https://github.com/catseye/SixtyPical/blob/master/doc/Analyzing.markdown)
* [Emitting](https://github.com/catseye/SixtyPical/blob/master/doc/Emitting.markdown)
* [Instruction Support](https://github.com/catseye/SixtyPical/blob/master/doc/Instruction_Support.markdown)
Internals
---------
@ -206,7 +211,6 @@ it probably won't.)
TODO
----
* Initial values for reserved tables
* Character tables ("strings" to everybody else)
* Addressing modes — indexed mode on more instructions
* Rename and lift temporaries in nested blocks

View File

@ -80,6 +80,55 @@ An address declared with `reserve` may be given an initial value.
| }
= True
A byte table declared with `reserve` may be given an initial value consisting
of a sequence of bytes.
| reserve byte[4] table : (0 $40 $10 20)
| routine main {
| ldy #0
| lda table, y
| }
| routine died {
| sta table, y
| }
= True
A byte table declared with `reserve` may be given an initial value consisting
of a sequence of bytes represented as a character string.
| reserve byte[4] table : "What"
| routine main {
| ldy #0
| lda table, y
| }
| routine died {
| sta table, y
| }
= True
When a byte table declared with `reserve` is given an initial value consisting
of a sequence of bytes, it must be the same length as the table is declared.
| reserve byte[4] table : (0 $40 $10 20 60 70 90)
| routine main {
| ldy #0
| lda table, y
| }
| routine died {
| sta table, y
| }
? initial table incorrect size
| reserve byte[4] table : "Hello, world!"
| routine main {
| ldy #0
| lda table, y
| }
| routine died {
| sta table, y
| }
? initial table incorrect size
An address may be declared with `locate`, which is like `.alias` in an
assembler, with the understanding that the value will be treated "like an
address." This is generally an address into the operating system or hardware

View File

@ -51,6 +51,19 @@ noUseOfUndeclaredRoutines p@(Program decls routines) =
False -> error ("undeclared routine '" ++ routName ++ "'") -- acc + 1
checkInstr other acc = acc
consistentInitialTableSizes p@(Program decls routines) =
let
inconsistentTableSizes = foldProgramDecls (checkDecl) 0 p
in
inconsistentTableSizes == 0
where
checkDecl (Reserve _ (ByteTable sz) []) acc = acc
checkDecl (Reserve _ (ByteTable sz) vals) acc =
case sz == (length vals) of
True -> acc
False -> acc + 1
checkDecl _ acc = acc
-- - - - - - -
checkAndTransformProgram :: Program -> Maybe Program
@ -60,7 +73,8 @@ checkAndTransformProgram program =
trueOrDie "duplicate location name" (noDuplicateDecls program) &&
trueOrDie "duplicate routine name" (noDuplicateRoutines program) &&
trueOrDie "undeclared routine" (noUseOfUndeclaredRoutines program) &&
trueOrDie "indexed access of non-table" (noIndexedAccessOfNonTables program)
trueOrDie "indexed access of non-table" (noIndexedAccessOfNonTables program) &&
trueOrDie "initial table incorrect size" (consistentInitialTableSizes program)
then
let
program' = numberProgramLoops program

View File

@ -25,15 +25,21 @@ emitDecls p (decl:decls) =
emitDecl p decl ++ "\n" ++ emitDecls p decls
emitDecl p (Assign name _ addr) = ".alias " ++ name ++ " " ++ (show addr)
emitDecl p (Reserve name typ (Just val))
emitDecl p (Reserve name typ [val])
| typ == Byte = name ++ ": .byte " ++ (show val)
| typ == Word = name ++ ": .word " ++ (show val)
| typ == Vector = name ++ ": .word " ++ (show val)
emitDecl p (Reserve name (ByteTable size) Nothing) =
emitDecl p (Reserve name (ByteTable size) []) =
".space " ++ name ++ " " ++ (show size)
emitDecl p (Reserve name typ Nothing)
emitDecl p (Reserve name (ByteTable size) vals) =
name ++ ": .byte " ++ (showList vals)
where
showList [] = ""
showList (val:vals) = (show val) ++ " " ++ (showList vals)
emitDecl p (Reserve name typ [])
| typ == Byte = ".space " ++ name ++ " 1"
| typ == Word = ".space " ++ name ++ " 2"
| typ == Vector = ".space " ++ name ++ " 2"

View File

@ -47,7 +47,7 @@ data StorageLocation = A
-- -- -- -- program model -- -- -- --
data Decl = Assign LocationName StorageType Address -- .alias
| Reserve LocationName StorageType (Maybe DataValue) -- .word, .byte
| Reserve LocationName StorageType [DataValue] -- .word, .byte
| External RoutineName Address
deriving (Show, Ord, Eq)
@ -109,8 +109,8 @@ isLocationDecl (Reserve _ _ _) = True
isLocationDecl _ = False
isInitializedDecl (Assign _ _ _) = False
isInitializedDecl (Reserve _ _ (Just _)) = True
isInitializedDecl (Reserve _ _ Nothing) = False
isInitializedDecl (Reserve _ _ (v:vs)) = True
isInitializedDecl (Reserve _ _ []) = False
declaredLocationNames (Program decls _) =
map (getDeclLocationName) (filter (isLocationDecl) decls)
@ -177,6 +177,13 @@ foldProgramRoutines :: (Instruction -> a -> a) -> a -> Program -> a
foldProgramRoutines f a (Program decls routs) =
foldRoutines f a routs
foldDecls :: (Decl -> a -> a) -> a -> [Decl] -> a
foldDecls = foldr
foldProgramDecls :: (Decl -> a -> a) -> a -> Program -> a
foldProgramDecls f a (Program decls routs) =
foldDecls f a decls
--
lookupDecl (Program decls _) name =

View File

@ -10,14 +10,15 @@ import SixtyPical.Model
{-
Toplevel := {Decl} {Routine}.
Decl := "reserve" StorageType LocationName [":" Literal]
| "assign" StorageType LocationName Literal
| "external" RoutineName Address.
StorageType := "byte" ["[" Literal "]"] | "word" | "vector".
Routine := "routine" RoutineName ["outputs" "(" {LocationName} ")"] Block.
Block := "{" {Decl} {Command} "}".
Command := "if" Branch Block "else" Block
Toplevel ::= {Decl} {Routine}.
Decl ::= "reserve" StorageType LocationName [":" InitialValue]
| "assign" StorageType LocationName Literal
| "external" RoutineName Address.
InitialValue ::= Literal | StringLiteral | "(" {Literal} ")".
StorageType ::= "byte" ["[" Literal "]"] | "word" | "vector".
Routine ::= "routine" RoutineName ["outputs" "(" {LocationName} ")"] Block.
Block ::= "{" {Decl} {Command} "}".
Command ::= "if" Branch Block "else" Block
| "lda" (LocationName | Immediate)
| "ldx" (LocationName | Immediate)
| "ldy" (LocationName | Immediate)
@ -31,7 +32,7 @@ Command := "if" Branch Block "else" Block
| "jmp" LocationName
| "jsr" RoutineName
| "nop".
Branch := "bcc" | "bcs" | "beq" | "bmi" | "bne" | "bpl" | "bvc" | "bvs".
Branch ::= "bcc" | "bcs" | "beq" | "bmi" | "bne" | "bpl" | "bvc" | "bvs".
-}
@ -68,10 +69,10 @@ reserve = do
nspaces
sz <- storage_type
name <- location_name
value <- option Nothing (do{ string ":";
nspaces;
x <- literal_data_value;
return $ Just x })
value <- option [] (do{ string ":";
nspaces;
x <- initial_value;
return x })
return $ Reserve name sz value
assign :: Parser Decl
@ -112,6 +113,24 @@ storage_type :: Parser StorageType
storage_type = (try $ byte_table) <|> (storage "byte" Byte) <|>
(storage "word" Word) <|> (storage "vector" Vector)
initial_value :: Parser [DataValue]
initial_value =
data_value_list <|> single_literal_data_value
where
single_literal_data_value = do
a <- literal_data_value
return [a]
data_value_list = do
string "("
nspaces
a <- many literal_data_value
string ")"
nspaces
return a
-- -- --
routine :: Parser Routine
routine = do
string "routine"
@ -625,7 +644,7 @@ hex_literal = do
decimal_literal :: Parser Int
decimal_literal = do
digits <- many digit
digits <- many1 digit
nspaces
return $ read digits

View File

@ -161,7 +161,7 @@ renameRoutineDecls id ((Routine name outputs block):routs) =
((Routine name outputs block'):rest)
foldDeclsRenaming [] id block = (id, block)
foldDeclsRenaming ((Reserve name typ Nothing):decls) id block =
foldDeclsRenaming ((Reserve name typ []):decls) id block =
let
newName = "_temp_" ++ (show id)
id' = id + 1
@ -176,8 +176,8 @@ foldDeclsRenaming ((Reserve name typ _):decls) id block =
substDeclName n1 n2 (Block decls instrs) =
Block (map (s) decls) instrs
where
s d@(Reserve name typ Nothing)
| name == n1 = (Reserve n2 typ Nothing)
s d@(Reserve name typ [])
| name == n1 = (Reserve n2 typ [])
| otherwise = d