Compare commits

...

5 Commits

Author SHA1 Message Date
6a16dc6150 better name for metas
Some checks failed
Publish Playground / build (push) Has been cancelled
Publish Playground / deploy (push) Has been cancelled
2026-02-11 13:32:45 -08:00
eb9921212c use record update for top 2026-02-11 13:32:09 -08:00
340457cab7 [ repl ] don't exit early on error 2026-02-09 11:04:05 -08:00
a17a9c4342 fix pipe issue in REPL, add ability to dump top in repl 2026-02-09 10:36:59 -08:00
08ed4178cf Fix FC on imports - make empty bounds the identity 2026-02-09 10:16:56 -08:00
15 changed files with 55 additions and 20 deletions

View File

@@ -47,6 +47,9 @@ export let shim: NodeShim = {
writeFileSync(name: string, data: string, enc?: string) { writeFileSync(name: string, data: string, enc?: string) {
shim.files[name] = new TextEncoder().encode(data) shim.files[name] = new TextEncoder().encode(data)
}, },
writeSync(fd: number, data: string) {
shim.stdout += data;
}
}, },
process: { process: {
argv: ["", ""], argv: ["", ""],

View File

@@ -484,6 +484,7 @@ const processOutput = (
let endLineNumber = +eline; let endLineNumber = +eline;
let endColumn = +ecol let endColumn = +ecol
// FIXME - pass the real path in // FIXME - pass the real path in
if (file.startsWith("./")) file = file.slice(2);
if (fn && fn !== file) { if (fn && fn !== file) {
startLineNumber = startColumn = 0; startLineNumber = startColumn = 0;
} }

View File

@@ -20,12 +20,16 @@ for fn in tests/*.newt ; do
echo "Compile failure mismatch for $fn" echo "Compile failure mismatch for $fn"
diff ${fn}.fail tmp/${bn}.compile diff ${fn}.fail tmp/${bn}.compile
failed=$((failed + 1)) failed=$((failed + 1))
if [ $1 = "--fix" ]; then
cp tmp/${bn}.compile ${fn}.fail
fi
continue continue
fi fi
elif [ $cerr != "0" ]; then elif [ $cerr != "0" ]; then
echo Compile failed for $fn echo Compile failed for $fn
failed=$((failed + 1)) failed=$((failed + 1))
cat tmp/${bn}.compile cat tmp/${bn}.compile
continue continue
fi fi
# if there is a golden file, run the code and compare output # if there is a golden file, run the code and compare output
@@ -40,6 +44,9 @@ for fn in tests/*.newt ; do
echo "Output mismatch for $fn" echo "Output mismatch for $fn"
diff ${fn}.golden tmp/${bn}.out diff ${fn}.golden tmp/${bn}.out
failed=$((failed + 1)) failed=$((failed + 1))
if [ $1 = "--fix" ]; then
cp tmp/${bn}.out ${fn}.golden
fi
fi fi
fi fi
done done

View File

@@ -15,9 +15,15 @@ record Bounds where
-- FIXME we should handle overlap and out of order.. -- FIXME we should handle overlap and out of order..
instance Add Bounds where instance Add Bounds where
a + b = a + b =
if empty a then b
else if empty b then a else
let a' = if a.startLine < b.startLine || a.startLine == b.startLine && a.startCol < b.startCol then a else b let a' = if a.startLine < b.startLine || a.startLine == b.startLine && a.startCol < b.startCol then a else b
b' = if a.endLine < b.endLine || a.endLine == b.endLine && a.endCol < b.endCol then b else a b' = if a.endLine < b.endLine || a.endLine == b.endLine && a.endCol < b.endCol then b else a
in MkBounds a'.startLine a'.startCol b'.endLine b'.endCol in MkBounds a'.startLine a'.startCol b'.endLine b'.endCol
where
empty : Bounds Bool
empty (MkBounds 0 0 0 0) = True
empty _ = False
instance Eq Bounds where instance Eq Bounds where
(MkBounds sl sc el ec) == (MkBounds sl' sc' el' ec') = (MkBounds sl sc el ec) == (MkBounds sl' sc' el' ec') =

View File

@@ -363,6 +363,8 @@ lams Z _ tm = tm
lams (S k) Nil tm = Lam emptyFC "arg_\{show k}" Explicit Many (lams k Nil tm) lams (S k) Nil tm = Lam emptyFC "arg_\{show k}" Explicit Many (lams k Nil tm)
lams (S k) (x :: xs) tm = Lam emptyFC x Explicit Many (lams k xs tm) lams (S k) (x :: xs) tm = Lam emptyFC x Explicit Many (lams k xs tm)
unify : Env -> UnifyMode -> Val -> Val -> M UnifyResult unify : Env -> UnifyMode -> Val -> Val -> M UnifyResult
.boundNames : Context -> List String .boundNames : Context -> List String
@@ -626,7 +628,7 @@ freshMeta ctx fc ty kind = do
debug $ \ _ => "fresh meta \{show mc.next} : \{show ty} (\{show kind})" debug $ \ _ => "fresh meta \{show mc.next} : \{show ty} (\{show kind})"
-- need the ns here -- need the ns here
-- we were fudging this for v1 -- we were fudging this for v1
let qn = QN top.ns "\{show mc.next}" let qn = QN top.ns "$m\{show mc.next}"
let newmeta = Unsolved fc qn ctx ty kind Nil let newmeta = Unsolved fc qn ctx ty kind Nil
let autos = case kind of let autos = case kind of
AutoSolve => qn :: mc.autos AutoSolve => qn :: mc.autos
@@ -1525,6 +1527,7 @@ check ctx tm ty = do
(tm,ty) => do (tm,ty) => do
(tm', ty') <- infer ctx tm (tm', ty') <- infer ctx tm
-- REVIEW - should we look at `tm` to know how many to insert? Is there a case where this helps?
(tm', ty') <- insert ctx tm' ty' (tm', ty') <- insert ctx tm' ty'
let names = map fst ctx.types let names = map fst ctx.types

View File

@@ -14,6 +14,7 @@ data ReplCommand
| GetDoc String | GetDoc String
| BrowseCmd QName | BrowseCmd QName
| HelpCmd | HelpCmd
| DumpTop
kw : String Parser String kw : String Parser String
kw s = satisfy (\t => t.val.text == s) "Expected \{show s}" kw s = satisfy (\t => t.val.text == s) "Expected \{show s}"
@@ -61,6 +62,7 @@ commands
:: MkCmd ":d" "document function" ArgIdent GetDoc :: MkCmd ":d" "document function" ArgIdent GetDoc
:: MkCmd ":doc" "document function" ArgIdent GetDoc :: MkCmd ":doc" "document function" ArgIdent GetDoc
:: MkCmd ":b" "browse namespace" ArgQName BrowseCmd :: MkCmd ":b" "browse namespace" ArgQName BrowseCmd
:: MkCmd ":top" "dump top context as json" ArgNone DumpTop
-- type at point -- type at point
-- solve hole -- solve hole
-- search by prefix (for autocomplete - ideally include types at point, but we'd need recovery) -- search by prefix (for autocomplete - ideally include types at point, but we'd need recovery)

View File

@@ -54,8 +54,7 @@ writeSource fn = do
:: Nil) :: Nil)
++ map (render 90 noAlt) docs ++ map (render 90 noAlt) docs
(Right _) <- liftIO {M} $ writeFile fn src (Right _) <- liftIO {M} $ writeFile fn src
| Left err => exitFailure (show err) | Left err => throwError $ E (MkFC fn $ MkBounds 0 0 0 0) err
-- (Right _) <- chmodRaw fn 493 | Left err => exitFailure (show err)
pure MkUnit pure MkUnit
@@ -105,22 +104,22 @@ processModule importFC base stk qn@(QN ns nm) = do
modifyTop [modules := updateMap modns (emptyModCtx "") top.modules] modifyTop [modules := updateMap modns (emptyModCtx "") top.modules]
let fn = (joinBy "/" (base :: ns)) ++ "/" ++ nm ++ ".newt" let fn = (joinBy "/" (base :: ns)) ++ "/" ++ nm ++ ".newt"
(Right src) <- liftIO {M} $ readFile fn (Right src) <- liftIO {M} $ readFile fn
| Left err => exitFailure "ERROR at \{show importFC}: error reading \{fn}: \{show err}" | Left err => throwError $ E importFC "error reading \{fn}: \{show err}"
let (Right toks) = tokenise fn src let (Right toks) = tokenise fn src
| Left err => exitFailure (showError src err) | Left err => throwError err
let (Right ((nameFC, modName), ops, toks)) = partialParse fn parseModHeader top.ops toks let (Right ((nameFC, modName), ops, toks)) = partialParse fn parseModHeader top.ops toks
| Left (err, toks) => exitFailure (showError src err) | Left (err, toks) => throwError err
log 1 $ \ _ => "scan imports for module \{modName}" log 1 $ \ _ => "scan imports for module \{modName}"
let ns = split modName "." let ns = split modName "."
let (path, modName') = unsnoc $ split1 modName "." let (path, modName') = unsnoc $ split1 modName "."
-- let bparts = split base "/" -- let bparts = split base "/"
let (True) = qn == QN path modName' let (True) = qn == QN path modName'
| _ => exitFailure "ERROR at \{show nameFC}: module name \{show modName} doesn't match file name \{show fn}" | _ => throwError $ E nameFC "module name \{show modName} doesn't match file name \{show fn}"
let (Right (imports, ops, toks)) = partialParse fn parseImports ops toks let (Right (imports, ops, toks)) = partialParse fn parseImports ops toks
| Left (err, toks) => exitFailure (showError src err) | Left (err, toks) => throwError err
let importNames = map importToQN imports let importNames = map importToQN imports
@@ -155,7 +154,13 @@ processModule importFC base stk qn@(QN ns nm) = do
top <- getTop top <- getTop
let freshMC = MC emptyMap Nil 0 CheckAll let freshMC = MC emptyMap Nil 0 CheckAll
-- set imported, mod, freshMC, ops before processing -- set imported, mod, freshMC, ops before processing
modifyTop (\ top => MkTop top.modules imported emptyMap modns emptyMap freshMC top.verbose top.errors ops) modifyTop [ imported := imported
; hints := emptyMap
; ns := modns
; defs := emptyMap
; metaCtx := freshMC
; ops := ops
]
for imported $ \ ns => do for imported $ \ ns => do
let (Just mod) = lookupMap' ns top.modules | _ => error emptyFC "namespace \{show ns} missing" let (Just mod) = lookupMap' ns top.modules | _ => error emptyFC "namespace \{show ns} missing"
importHints (listValues mod.modDefs) importHints (listValues mod.modDefs)
@@ -176,7 +181,7 @@ processModule importFC base stk qn@(QN ns nm) = do
logMetas $ reverse $ listValues top.metaCtx.metas logMetas $ reverse $ listValues top.metaCtx.metas
let (Nil) = top.errors let (Nil) = top.errors
| errors => exitFailure "Compile failed" | errors => throwError $ E importFC "Failed to compile module \{show qn}"
pure src pure src
where where
tryProcessDecl : String -> List String Decl -> M Unit tryProcessDecl : String -> List String Decl -> M Unit
@@ -200,7 +205,7 @@ showErrors fn src = do
let (Nil) = top.errors let (Nil) = top.errors
| errors => do | errors => do
traverse (putStrLn showError src) errors traverse (putStrLn showError src) errors
exitFailure "Compile failed" throwError $ E (MkFC fn $ MkBounds 0 0 0 0) "Compile failed"
pure MkUnit pure MkUnit
invalidateModule : QName -> M Unit invalidateModule : QName -> M Unit
@@ -235,7 +240,12 @@ processFile fn = do
top <- getTop top <- getTop
let modules = updateMap primNS (MkModCtx "" top.defs (MC emptyMap Nil 0 CheckAll) top.ops Nil) top.modules let modules = updateMap primNS (MkModCtx "" top.defs (MC emptyMap Nil 0 CheckAll) top.ops Nil) top.modules
modifyTop (\ top => MkTop modules (primNS :: Nil) emptyMap Nil emptyMap top.metaCtx top.verbose top.errors top.ops) modifyTop [ modules := modules
; imported := primNS :: Nil
; hints := emptyMap
; ns := Nil
; defs := emptyMap
]
invalidateModule qn invalidateModule qn
@@ -304,6 +314,9 @@ runCommand (GetDoc name) = getDoc name
runCommand (Verbose Nothing) = modifyTop [ verbose $= _+_ 1 ] runCommand (Verbose Nothing) = modifyTop [ verbose $= _+_ 1 ]
runCommand (Verbose (Just v)) = modifyTop [ verbose := v ] runCommand (Verbose (Just v)) = modifyTop [ verbose := v ]
runCommand (OutputJS fn) = writeSource fn runCommand (OutputJS fn) = writeSource fn
runCommand DumpTop = do
json <- jsonTopContext
putStrLn "TOP:\{renderJson json}"
-- Broken out to a separate function so I can hook it. -- Broken out to a separate function so I can hook it.
runString : String → M Unit runString : String → M Unit

View File

@@ -389,7 +389,7 @@ instance HasIO IO where
liftIO a = a liftIO a = a
pfunc primPutStrLn uses (MkIORes MkUnit) : String IO Unit := `(s) => (w) => { pfunc primPutStrLn uses (MkIORes MkUnit) : String IO Unit := `(s) => (w) => {
console.log(s) require('fs').writeSync(1, s + '\n')
return Prelude_MkIORes(Prelude_MkUnit,w) return Prelude_MkIORes(Prelude_MkUnit,w)
}` }`

View File

@@ -7,4 +7,4 @@ ERROR at tests/BadAlt.newt:6:6--6:13: Prelude._:<_ not a constructor for (Prelud
foo (xs :< x) = x foo (xs :< x) = x
^^^^^^^ ^^^^^^^
Compile failed ERROR at :1:1--1:2: Failed to compile module BadAlt

View File

@@ -6,4 +6,4 @@ ERROR at tests/Duplicate.newt:4:1--4:5: Duplicate.Left is already defined at tes
data Either : U -> U -> U where data Either : U -> U -> U where
^^^^ ^^^^
Compile failed ERROR at :1:1--1:2: Failed to compile module Duplicate

View File

@@ -3,4 +3,4 @@ module Prelude
module ErrMsg2 module ErrMsg2
ERROR at tests/ErrMsg2.newt:6:13--6:15: Expected '=>' at Keyword:-> ERROR at tests/ErrMsg2.newt:6:13--6:15: Expected '=>' at Keyword:->
Compile failed ERROR at :1:1--1:2: Failed to compile module ErrMsg2

View File

@@ -18,4 +18,4 @@ ERROR at tests/ErrorDup.newt:9:7--9:10: Nat already declared
class Nat where class Nat where
^^^ ^^^
Compile failed ERROR at :1:1--1:2: Failed to compile module ErrorDup

View File

@@ -6,4 +6,4 @@ ERROR at tests/LitConCase.newt:7:5--7:11: expected Prim.Int
foo MkUnit = MkUnit foo MkUnit = MkUnit
^^^^^^ ^^^^^^
Compile failed ERROR at :1:1--1:2: Failed to compile module LitConCase

View File

@@ -7,4 +7,4 @@ ERROR at tests/Possible.newt:6:5--6:8: possible constructors: [Prelude.Z, Prelud
foo () foo ()
^^^ ^^^
Compile failed ERROR at :1:1--1:2: Failed to compile module Possible

View File

@@ -7,4 +7,4 @@ ERROR at tests/Quantity.newt:11:15--11:16: used erased value x$0 (FIXME FC may b
bar {x} = foo x bar {x} = foo x
^ ^
Compile failed ERROR at :1:1--1:2: Failed to compile module Quantity