imports
This commit is contained in:
3
TODO.md
3
TODO.md
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
I may be done with `U` - I keep typing `Type`.
|
I may be done with `U` - I keep typing `Type`.
|
||||||
|
|
||||||
|
- [ ] Generate some programs that do stuff
|
||||||
|
- [ ] import
|
||||||
- [ ] consider making meta application implicit in term, so its more readable when printed
|
- [ ] consider making meta application implicit in term, so its more readable when printed
|
||||||
- Currently we have explicit `App` surrounding `Meta` when inserting metas. Some people
|
- Currently we have explicit `App` surrounding `Meta` when inserting metas. Some people
|
||||||
leave that implicit for efficiency. I think it would also make printing more readable.
|
leave that implicit for efficiency. I think it would also make printing more readable.
|
||||||
@@ -23,7 +25,6 @@ I may be done with `U` - I keep typing `Type`.
|
|||||||
- [x] case statements
|
- [x] case statements
|
||||||
- [x] SKIP list syntax
|
- [x] SKIP list syntax
|
||||||
- Agda doesn't have it, clashes with pair syntax
|
- Agda doesn't have it, clashes with pair syntax
|
||||||
- [ ] import
|
|
||||||
- [ ] autos / typeclass resolution
|
- [ ] autos / typeclass resolution
|
||||||
- We need special handling in unification to make this possible
|
- We need special handling in unification to make this possible
|
||||||
- options
|
- options
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
const diagnostics: vscode.Diagnostic[] = [];
|
const diagnostics: vscode.Diagnostic[] = [];
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
let start = new vscode.Position(0,0)
|
let start = new vscode.Position(0,0);
|
||||||
let end = new vscode.Position(0,1)
|
let end = new vscode.Position(0,1);
|
||||||
let range = document.getWordRangeAtPosition(start) ?? new vscode.Range(start,end)
|
let range = document.getWordRangeAtPosition(start) ?? new vscode.Range(start,end);
|
||||||
const diag = new vscode.Diagnostic(range, "newt execution failed", vscode.DiagnosticSeverity.Error)
|
const diag = new vscode.Diagnostic(range, "newt execution failed", vscode.DiagnosticSeverity.Error);
|
||||||
diagnostics.push(diag)
|
diagnostics.push(diag);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "keyword.newt",
|
"name": "keyword.newt",
|
||||||
"match": "\\b(data|where|case|of|let|in|U|module|ptype|pfunc|infix|infixl|infixr)\\b"
|
"match": "\\b(data|where|case|of|let|in|U|module|import|ptype|pfunc|infix|infixl|infixr)\\b"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module Equality
|
module Equality1
|
||||||
|
|
||||||
-- Leibniz equality
|
-- Leibniz equality
|
||||||
Eq : {A : U} -> A -> A -> U
|
Eq : {A : U} -> A -> A -> U
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
module Oper
|
|
||||||
|
|
||||||
-- These are hard-coded at the moment
|
|
||||||
-- For now they must be of the form _op_, we'll circle back
|
|
||||||
-- with a different parser, but that works today.
|
|
||||||
|
|
||||||
-- this will be parsed as a top level decl, collected in TopContext, and
|
|
||||||
-- injected into the Parser. It'll need to be passed around or available
|
|
||||||
-- for read in the monad.
|
|
||||||
|
|
||||||
-- long term, I might want TopContext in the parser, and parse a top-level
|
|
||||||
-- declaration at a time (for incremental updates), but much longer term.
|
|
||||||
|
|
||||||
infixl 4 _+_
|
|
||||||
infixl 4 _-_
|
|
||||||
infixl 5 _*_
|
|
||||||
infixl 5 _/_
|
|
||||||
|
|
||||||
ptype Int
|
|
||||||
ptype String
|
|
||||||
ptype JVoid
|
|
||||||
|
|
||||||
-- If we had a different quote here, we could tell vscode it's javascript.
|
|
||||||
-- or actually just switch modes inside pfunc
|
|
||||||
pfunc log : String -> JVoid := "(x) => console.log(x)"
|
|
||||||
pfunc plus : Int -> Int -> Int := "(x,y) => x + y"
|
|
||||||
pfunc _*_ : Int -> Int -> Int := "(x,y) => x * y"
|
|
||||||
|
|
||||||
-- We now have to clean JS identifiers
|
|
||||||
_+_ : Int -> Int -> Int
|
|
||||||
_+_ x y = plus x y
|
|
||||||
|
|
||||||
test : Int -> Int
|
|
||||||
test x = 42 + x * 3 + 2
|
|
||||||
|
|
||||||
infixr 2 _,_
|
|
||||||
data Pair : U -> U -> U where
|
|
||||||
_,_ : {A B : U} -> A -> B -> Pair A B
|
|
||||||
|
|
||||||
blah : Int -> Int -> Int -> Pair Int (Pair Int Int)
|
|
||||||
blah x y z = (x, y, z)
|
|
||||||
|
|
||||||
curryPlus : Pair Int Int -> Int
|
|
||||||
curryPlus (a, b) = a + b
|
|
||||||
|
|
||||||
caseCurry : Pair Int Int -> Int
|
|
||||||
caseCurry x = case x of
|
|
||||||
(a,b) => a + b
|
|
||||||
@@ -342,8 +342,6 @@ parseMod : Parser Module
|
|||||||
parseMod = do
|
parseMod = do
|
||||||
keyword "module"
|
keyword "module"
|
||||||
name <- uident
|
name <- uident
|
||||||
-- probably should be manySame, and we want to start with col -1
|
|
||||||
-- if we enforce blocks indent more than parent
|
|
||||||
decls <- startBlock $ manySame $ parseDecl
|
decls <- startBlock $ manySame $ parseDecl
|
||||||
pure $ MkModule name decls
|
pure $ MkModule name decls
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ processDecl (DCheck fc tm ty) = do
|
|||||||
putStrLn "norm \{pprint [] norm}"
|
putStrLn "norm \{pprint [] norm}"
|
||||||
putStrLn "NF "
|
putStrLn "NF "
|
||||||
|
|
||||||
processDecl (DImport fc str) = throwError $ E fc "import not implemented"
|
processDecl (DImport fc str) = pure ()
|
||||||
|
|
||||||
processDecl (Data fc nm ty cons) = do
|
processDecl (Data fc nm ty cons) = do
|
||||||
ctx <- get
|
ctx <- get
|
||||||
|
|||||||
56
src/Main.idr
56
src/Main.idr
@@ -23,8 +23,24 @@ import Lib.Syntax
|
|||||||
import System
|
import System
|
||||||
import System.Directory
|
import System.Directory
|
||||||
import System.File
|
import System.File
|
||||||
|
import System.Path
|
||||||
|
|
||||||
fail : String -> M ()
|
{-
|
||||||
|
|
||||||
|
import
|
||||||
|
|
||||||
|
need to find the file.
|
||||||
|
- get base directory
|
||||||
|
- . to /
|
||||||
|
- add .newt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
loop back to processFile
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
fail : String -> M a
|
||||||
fail msg = putStrLn msg >> exitFailure
|
fail msg = putStrLn msg >> exitFailure
|
||||||
|
|
||||||
dumpContext : TopContext -> M ()
|
dumpContext : TopContext -> M ()
|
||||||
@@ -42,19 +58,45 @@ dumpSource = do
|
|||||||
doc <- compile
|
doc <- compile
|
||||||
putStrLn $ render 90 doc
|
putStrLn $ render 90 doc
|
||||||
|
|
||||||
processFile : String -> M ()
|
parseFile : String -> M (String,Module)
|
||||||
processFile fn = do
|
parseFile fn = do
|
||||||
putStrLn "*** Process \{fn}"
|
|
||||||
Right src <- readFile $ fn
|
Right src <- readFile $ fn
|
||||||
| Left err => printLn err
|
| Left err => fail (show err)
|
||||||
let toks = tokenise src
|
let toks = tokenise src
|
||||||
let Right res = parse parseMod toks
|
let Right res = parse parseMod toks
|
||||||
| Left y => fail (showError src y)
|
| Left y => fail (showError src y)
|
||||||
putStrLn $ render 80 $ pretty res
|
pure (src, res)
|
||||||
printLn "process Decls"
|
|
||||||
|
loadModule : String -> String -> M ()
|
||||||
|
loadModule base name = do
|
||||||
|
let fn = base ++ "/" ++ name ++ ".newt"
|
||||||
|
(src, res) <- parseFile fn
|
||||||
|
putStrLn "module \{res.name}"
|
||||||
|
let True = name == res.name
|
||||||
|
| _ => fail "module name \{show res.name} doesn't match file name \{show fn}"
|
||||||
|
-- TODO separate imports and detect loops / redundant
|
||||||
|
for_ res.decls $ \ decl => case decl of
|
||||||
|
(DImport x str) => loadModule base str
|
||||||
|
_ => pure ()
|
||||||
|
|
||||||
|
|
||||||
|
putStrLn "process Decls"
|
||||||
Right _ <- tryError $ traverse_ processDecl (collectDecl res.decls)
|
Right _ <- tryError $ traverse_ processDecl (collectDecl res.decls)
|
||||||
| Left y => fail (showError src y)
|
| Left y => fail (showError src y)
|
||||||
|
|
||||||
|
pure ()
|
||||||
|
|
||||||
|
processFile : String -> M ()
|
||||||
|
processFile fn = do
|
||||||
|
putStrLn "*** Process \{fn}"
|
||||||
|
(src, res) <- parseFile fn
|
||||||
|
putStrLn "module \{res.name}"
|
||||||
|
let parts = splitPath fn
|
||||||
|
let file = fromMaybe "" $ last' parts
|
||||||
|
let dir = fromMaybe "./" $ parent fn
|
||||||
|
let (base,ext) = splitFileName (fromMaybe "" $ last' parts)
|
||||||
|
putStrLn "\{show dir} \{show base} \{show ext}"
|
||||||
|
loadModule dir base
|
||||||
top <- get
|
top <- get
|
||||||
dumpContext top
|
dumpContext top
|
||||||
dumpSource
|
dumpSource
|
||||||
|
|||||||
14
tests/black/Prelude.newt
Normal file
14
tests/black/Prelude.newt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
module Prelude
|
||||||
|
|
||||||
|
data Nat : U where
|
||||||
|
Z : Nat
|
||||||
|
S : Nat -> Nat
|
||||||
|
|
||||||
|
data Maybe : U -> U where
|
||||||
|
Just : {a : U} -> a -> Maybe a
|
||||||
|
Nothing : {a : U} -> Maybe a
|
||||||
|
|
||||||
|
data Either : U -> U -> U where
|
||||||
|
Left : {a b : U} -> a -> Either a b
|
||||||
|
Right : {a b : U} -> b -> Either a b
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module Scratch
|
module Test1
|
||||||
|
|
||||||
nat : U
|
nat : U
|
||||||
nat = {C : U} -> C -> (nat -> C) -> C
|
nat = {C : U} -> C -> (nat -> C) -> C
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module Scratch
|
module TestCase
|
||||||
|
|
||||||
-- I'm testing cases here, but using examples carefully design to be
|
-- I'm testing cases here, but using examples carefully design to be
|
||||||
-- simple case trees. Patterns are a var or a constructor applied to vars.
|
-- simple case trees. Patterns are a var or a constructor applied to vars.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module Scratch
|
module TestCase2
|
||||||
|
|
||||||
data Nat : U where
|
data Nat : U where
|
||||||
Z : Nat
|
Z : Nat
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module Scratch2
|
module TestCase3
|
||||||
|
|
||||||
data Nat : U where
|
data Nat : U where
|
||||||
Z : Nat
|
Z : Nat
|
||||||
7
tests/black/TestImport.newt
Normal file
7
tests/black/TestImport.newt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
module TestImport
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
one : Nat
|
||||||
|
one = S Z
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module Zoo2
|
module Zoo2eg
|
||||||
|
|
||||||
id : (A : U) -> A -> A
|
id : (A : U) -> A -> A
|
||||||
id = \ A x => x
|
id = \ A x => x
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module Zoo3
|
module Zoo3eg
|
||||||
|
|
||||||
id : (A : _) -> A -> A
|
id : (A : _) -> A -> A
|
||||||
id = \ A x => x
|
id = \ A x => x
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module Zoo4
|
module Zoo4eg
|
||||||
|
|
||||||
id : {A : U} -> A -> A
|
id : {A : U} -> A -> A
|
||||||
id = \x => x -- elaborated to \{A} x. x
|
id = \x => x -- elaborated to \{A} x. x
|
||||||
Reference in New Issue
Block a user