Skip to content

Commit 164dbdb

Browse files
[ new ] basic readFrom directive
1 parent 52ab8f3 commit 164dbdb

File tree

6 files changed

+79
-10
lines changed

6 files changed

+79
-10
lines changed

LabMate.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.4
22
name: LabMate
3-
version: 0.2.0.4
3+
version: 0.2.0.5
44

55
-- A short (one-line) description of the package.
66
-- synopsis:

emacs/labmate.el

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
;; handling comments
4444
:syntax-table (make-syntax-table)
4545
;; code for syntax highlighting
46-
(font-lock-add-keywords nil '(("^\s*%>[^%\n]+" . 'labmate-directive)))
46+
(font-lock-add-keywords nil '(("^\s*%>[^%\n]+" 0 'labmate-directive t)))
4747
(font-lock-add-keywords nil '(("^\s*%<.+" . 'labmate-response-error)))
4848
(font-lock-add-keywords nil '(("^\s*%<[{}]$" . 'labmate-response-delimiter)))
4949
(font-lock-add-keywords nil '(("^\s*%<\s*renamed[^%\n]+" . 'labmate-response-success)))

examples/imeko.m

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
1-
%%> times :: [ 1 x 12 ] double
1+
% %> dimensions V for Q over metre for `Length, kg for `Mass, sec for `Time
22

3-
%%> voltages :: [ 1 x 12 ] double
3+
%> times :: [ 1 x 12 ] double
4+
%> voltages :: [ 1 x 12 ] double
45

6+
%> readfrom 'inputs.txt' times voltages
57

68
%> z3 :: [ 3 x 1 ] double
79
z3 = [ 0; 0; 0 ]
810
%> i3 :: [ 3 x 1 ] double
911
i3 = [ 1; 1; 1 ]
1012

11-
% %> ddnc :: [ 12 x 4 ] double
1213
ddnc = [ i3 z3 i3 z3
1314
-i3 z3 i3 z3
1415
z3 i3 z3 i3
1516
z3 -i3 z3 i3 ]
1617
%> typeof ddnc
1718

18-
%M = [ ddnc times' ]
19-
%%> typeof M
19+
M = [ ddnc times' ]
20+
%> typeof M
21+
22+
x = M \ voltages'
23+
%> typeof x
24+
2025

21-
%x = M \ voltages
22-
%%> typeof x

src/Machine.hs

+63-1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ instance PrettyPrint DiagnosticData where
128128
pure ["unit $" ++ show un ++ " " ++ stat ++ " $" ++ show tn]
129129
pprint (UnitDs units) =
130130
pure ["units" ++ foldMap (\u -> " $" ++ show (nonce u)) units]
131+
pprint (ReadFromD filename vars) =
132+
pure ["readfrom" ++ filename ++ " " ++ show vars]
131133

132134
instance PrettyPrint Frame where
133135
pprint (Declaration n UserDecl{..}) = do
@@ -165,6 +167,7 @@ data DiagnosticData
165167
Expr {- e, t = elab e -}
166168
| UnitD Nonce BOOL Nonce
167169
| UnitDs [WithSource String]
170+
| ReadFromD String [Either String (String, TYPE)]
168171
deriving Show
169172

170173
data Frame where
@@ -1966,6 +1969,15 @@ runDirective rl (dir :<=: src, body) = do
19661969
InputFormat name | Just (InputFormatBody body) <- body -> do
19671970
newProb $ InputFormatAction name body rl
19681971
run
1972+
ReadFrom filename variables -> do
1973+
vs <- for variables $ \ v -> findDeclaration (UserDecl{varTy = Nothing, currentName = v, seen = False, newNames = [], capturable = False, whereAmI = MatLab}) >>= \case
1974+
Just (name, ty) -> do
1975+
pushDefinition name (E $^ M (name, Zy) $^ S0 $^ U :^ Ze)
1976+
pure $ Right (v, ty)
1977+
Nothing -> pure $ Left $ "Unknown variable " ++ v
1978+
push $ Diagnostic rl (ReadFromD filename vs)
1979+
newProb $ Done nil
1980+
run
19691981
Declare xs ty -> do
19701982
(sol, prob) <- elab "declType" emptyContext (atom SType) (TensorTask <$> ty)
19711983
pushProblems (Sourced . fmap (DeclareAction sol) <$> xs)
@@ -2871,6 +2883,10 @@ normaliseFrame = \case
28712883
stat <- normalise VN (atom STwo) stat
28722884
pure $ UnitD un stat tn
28732885
normaliseDiagnostic d@(UnitDs _) = pure d
2886+
normaliseDiagnostic d@(ReadFromD filename vs) = do
2887+
vs <- traverse (either (pure . Left)
2888+
(\ (s, ty) -> (Right . (s,)) <$> normalise emptyContext (atom SType) ty)) vs
2889+
pure $ ReadFromD filename vs
28742890

28752891
cleanup :: Mood -> Elab ()
28762892
cleanup mood = do
@@ -2952,7 +2968,53 @@ diagnosticRun = llup >>= \case
29522968
units ++
29532969
[ spc dent, sym "%<}"
29542970
]
2955-
2971+
ReadFromD filename vars -> go vars >>= \case
2972+
Left err -> pure $ [ Tok "\n" Ret dump, spc dent, sym "%<", spc 1] ++ err
2973+
Right code -> pure $ [ Tok "\n" Ret dump, spc dent, sym "%<{"]
2974+
++ concatMap (\ x -> Tok "\n" Ret dump:spc dent:x)
2975+
(preamble ++ code) ++ [ Tok "\n" Ret dump, spc dent, sym "%<}"]
2976+
where
2977+
preamble = [[sym ("h=fopen(\'" ++ filename ++ "\');")]
2978+
,[sym "c=textscan(h,\'%f\');"]
2979+
,[sym "fclose(h);"]
2980+
,[sym "src = c{1};"]
2981+
,[sym "readPtr = 1;"]
2982+
]
2983+
go :: [Either String (String, TYPE)] -> Elab (Either [Tok] [[Tok]])
2984+
go [] = pure $ Right []
2985+
go (Left err:vs) = pure $ Left [ sym err ]
2986+
go (Right (v, ty):vs) = readFromType emptyContext v ty >>= \case
2987+
Right code -> go vs >>= \case
2988+
Left err -> pure $ Left $ err
2989+
Right codes -> pure $ Right $ code ++ codes
2990+
Left err -> pure $ Left err
2991+
2992+
readFromType :: NATTY n => Context n -> String -> Typ ^ n -> Elab (Either [Tok] [[Tok]])
2993+
readFromType ctx var ty = do
2994+
ty <- normalise ctx (atom SType) ty
2995+
case tagEh ty of
2996+
_ | ty == doubleType -< no (scopeOf ty) -> pure $ Right $ readSingle
2997+
Just (SAbel, [ty]) | isUnitType ty -> pure $ Right readSingle
2998+
Just (SMatrix, [rowGenTy, colGenTy, cellTy, rs, cs])
2999+
| Just (i, cellTy) <- lamNameEh cellTy, Just (j, cellTy) <- lamNameEh cellTy
3000+
, rs <- listView rs, cs <- listView cs, all isRight rs, all isRight cs -> do
3001+
let ctx' = ctx \\\ (i, mk SAbel rowGenTy) \\\ (j, wk $ mk SAbel colGenTy)
3002+
cellTy <- normalise ctx' (atom SType) cellTy
3003+
case (length rs, length cs) of
3004+
(1, 1) -> readFromType ctx' var cellTy
3005+
(1, c) -> fmap (\ s -> [[sym ("for i = 1:" ++ show c)]] ++ map (spc 2:) s ++ [[sym "end"]])
3006+
<$> (readFromType ctx' (var ++ "(i)") cellTy)
3007+
(r, 1) -> fmap (\ s -> [[sym ("for i = 1:" ++ show r)]] ++ map (spc 2:) s ++ [[sym "end"]])
3008+
<$> (readFromType ctx' (var ++ "(i,1)") cellTy)
3009+
(r, c) -> fmap (\ s -> [[sym ("for i = 1:" ++ show r)], [spc 2, sym ("for j = 1:" ++ show c)]]
3010+
++ map (spc 4:) s ++ [[spc 4, sym "end"], [sym "end"]])
3011+
<$> (readFromType ctx' (var ++ "(i,j)") cellTy)
3012+
Just (SQuantity, [enumTy, exp]) -> pure $ Right $ readSingle -- TODO: require unit
3013+
_ -> do
3014+
ty <- unelabType ctx ty
3015+
pure $ Left ([sym "I do not know how to generate code to read from type "] ++ ty)
3016+
where
3017+
readSingle = [[sym (var ++ " = src(readPtr);")], [sym "readPtr = readPtr + 1;"]]
29563018

29573019
metaStatus :: Name -> Elab Status
29583020
metaStatus x = do

src/Parse/Matlab.hs

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ pdirhead :: Parser DirHeader
120120
pdirhead = Declare <$> psep1 (pspc <|> punc ",") (pws pnomNotLabMateKey) <* pospc <* psym "::" <* pospc <*> ptensortype
121121
<|> Rename <$ pkin Nom "rename" <* pospc <*> pnomNotLabMateKey <* pspc <*> pnomNotLabMateKey
122122
<|> InputFormat <$ pkin Nom "input" <* pospc <*> pnom
123+
<|> ReadFrom <$ pkin Nom "readfrom" <* pospc <*> pstringlit <* pspc <*> psep1 pspc pnom
123124
<|> Typecheck <$ pkin Nom "typecheck" <* pospc <*> ptensortype <* pspc <*> pexpr topCI
124125
<|> SynthType <$ pkin Nom "typeof" <* pospc <*> pexpr topCI
125126
<|> Dimensions <$ pkin Nom "dimensions" <* pspc

src/Syntax.hs

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ data DirHeader
3232
= Declare [WithSource String] ConcreteType
3333
| Rename String String
3434
| InputFormat String {- name of function -}
35+
| ReadFrom
36+
String -- filename
37+
[String] -- variables to generate code for
3538
| Typecheck ConcreteType Expr
3639
| SynthType Expr
3740
| Dimensions

0 commit comments

Comments
 (0)