cleanup
This commit is contained in:
1
TODO.md
1
TODO.md
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
|
- [ ] Raw is duplicated between Lib.Syntax and Lib.Compile, but not detected
|
||||||
- [ ] vscode - run newt when switching editors
|
- [ ] vscode - run newt when switching editors
|
||||||
- [ ] case split
|
- [ ] case split
|
||||||
- We could fake this up:
|
- We could fake this up:
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
- workaround is to visit the file first
|
- workaround is to visit the file first
|
||||||
- we can put them in the zip file and pull them over the IPC
|
- we can put them in the zip file and pull them over the IPC
|
||||||
- [ ] make phone layout automatic
|
- [ ] make phone layout automatic
|
||||||
|
- [ ] case split &c
|
||||||
- [x] move newt to a worker (shim + newt + listener)
|
- [x] move newt to a worker (shim + newt + listener)
|
||||||
- [x] tabs for source, compiler output
|
- [x] tabs for source, compiler output
|
||||||
- [x] Show errors in editor
|
- [x] Show errors in editor
|
||||||
@@ -19,4 +20,6 @@
|
|||||||
- [x] save to url (copy from idris2-playground)
|
- [x] save to url (copy from idris2-playground)
|
||||||
- [ ] click on url
|
- [ ] click on url
|
||||||
- [ ] settings
|
- [ ] settings
|
||||||
|
- compilation is now optional, what else do we need for newt?
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
/-
|
/-
|
||||||
Ok, so this is newt, a dependent typed programming language that
|
This is newt, a self-hosted, dependent typed programming language that
|
||||||
I am implementing to learn how they work. It targets javascript
|
compiles to javascript and borrows a lot of syntax from Idris and Agda.
|
||||||
and borrows a lot of syntax from Idris and Agda.
|
|
||||||
|
|
||||||
This page is a very simple web playground based on the monaco editor.
|
This page is a very simple web playground based on the codemirror editor.
|
||||||
It runs newt, compiled by Idris2, in a web worker.
|
It runs newt in a web worker.
|
||||||
|
|
||||||
Block comments follow Lean because they're easier to type on a
|
Block comments follow Lean because they're easier to type on a
|
||||||
US keyboard.
|
US keyboard.
|
||||||
|
|
||||||
The output, to the right, is somewhat noisy and obtuse. You'll see
|
|
||||||
INFO and sometimes ERROR messages that show up in the editor view
|
|
||||||
on hover. I'm emitting INFO for solved metas.
|
|
||||||
|
|
||||||
The Day1.newt and Day2.newt are last year's advent of code, translated
|
|
||||||
from Lean.
|
|
||||||
|
|
||||||
-/
|
-/
|
||||||
|
|
||||||
-- One-line comments begin with two hyphens
|
-- One-line comments begin with two hyphens
|
||||||
@@ -27,10 +19,11 @@
|
|||||||
module Tour
|
module Tour
|
||||||
|
|
||||||
-- We can import other modules, with a flat namespace and no cycles,
|
-- We can import other modules, with a flat namespace and no cycles,
|
||||||
-- diamonds are ok
|
-- diamonds are ok, Prelude is not imported by default, only explicitly
|
||||||
|
-- imported modules are in scope
|
||||||
|
|
||||||
-- commented out until we preload other files into the worker
|
-- commented out because we redefine parts of Prelude in this file.
|
||||||
-- import Lib
|
-- import Prelude
|
||||||
|
|
||||||
-- We're calling the universe U and are doing type in type for now
|
-- We're calling the universe U and are doing type in type for now
|
||||||
|
|
||||||
@@ -39,10 +32,14 @@ data Nat : U where
|
|||||||
Z : Nat
|
Z : Nat
|
||||||
S : Nat -> Nat
|
S : Nat -> Nat
|
||||||
|
|
||||||
|
-- Nat-shaped data is turned into numbers in codegen.
|
||||||
|
|
||||||
-- Multiple names are allowed on the left:
|
-- Multiple names are allowed on the left:
|
||||||
data Bool : U where
|
data Bool : U where
|
||||||
True False : Bool
|
True False : Bool
|
||||||
|
|
||||||
|
-- Enum shaped data becomes a bare string (the constructor name) in codegen.
|
||||||
|
|
||||||
-- function definitions are equations using dependent pattern matching
|
-- function definitions are equations using dependent pattern matching
|
||||||
plus : Nat -> Nat -> Nat
|
plus : Nat -> Nat -> Nat
|
||||||
plus Z m = m
|
plus Z m = m
|
||||||
@@ -58,7 +55,7 @@ plus' = \ n m => case n of
|
|||||||
|
|
||||||
-- We can define operators. Mixfix is supported, but we don't
|
-- We can define operators. Mixfix is supported, but we don't
|
||||||
-- allow ambiguity (so you can't have both [_] and [_,_]). See
|
-- allow ambiguity (so you can't have both [_] and [_,_]). See
|
||||||
-- the Reasoning.newt sample for a mixfix example.
|
-- the Reasoning.newt sample file for a mixfix example.
|
||||||
infixl 2 _≡_
|
infixl 2 _≡_
|
||||||
|
|
||||||
-- Here is an equality, like Idris, everything goes to the right of the colon
|
-- Here is an equality, like Idris, everything goes to the right of the colon
|
||||||
@@ -84,8 +81,6 @@ instance Add Nat where
|
|||||||
Z + m = m
|
Z + m = m
|
||||||
(S n) + m = S (n + m)
|
(S n) + m = S (n + m)
|
||||||
|
|
||||||
-- and it now finds the implicits, you'll see the solutions to the
|
|
||||||
-- implicits if you hover over the `+`.
|
|
||||||
two : Nat
|
two : Nat
|
||||||
two = S Z + S Z
|
two = S Z + S Z
|
||||||
|
|
||||||
@@ -96,14 +91,13 @@ foo a b = ?
|
|||||||
|
|
||||||
-- Newt compiles to javascript, there is a tab to the right that shows the
|
-- Newt compiles to javascript, there is a tab to the right that shows the
|
||||||
-- javascript output. There is some erasure, but inlining is not being done
|
-- javascript output. There is some erasure, but inlining is not being done
|
||||||
-- yet. Dead code elimination will be done if there is a `main` function.
|
-- yet.
|
||||||
-- That is not the case in this file.
|
|
||||||
|
|
||||||
-- We can define native types, if the type is left off, it defaults to U
|
-- We can define native types, if the type is left off, it defaults to U
|
||||||
|
|
||||||
ptype SomePrimType : U
|
ptype SomePrimType : U
|
||||||
|
|
||||||
-- The names of these three types are special, primitive numbers, strings,
|
-- The types Int, String, Char are special. Primitive numbers, strings,
|
||||||
-- and characters inhabit them, respectively. We can match on primitives, but
|
-- and characters inhabit them, respectively. We can match on primitives, but
|
||||||
-- must provide a default case:
|
-- must provide a default case:
|
||||||
|
|
||||||
@@ -208,3 +202,25 @@ prod xs ys = do
|
|||||||
y <- ys
|
y <- ys
|
||||||
pure (x, y)
|
pure (x, y)
|
||||||
|
|
||||||
|
|
||||||
|
data Unit = MkUnit
|
||||||
|
|
||||||
|
ptype World
|
||||||
|
|
||||||
|
data IORes a = MkIORes a World
|
||||||
|
|
||||||
|
IO : U -> U
|
||||||
|
IO a = World -> IORes a
|
||||||
|
|
||||||
|
instance Monad IO where
|
||||||
|
bind ma mab = \ w => case ma w of
|
||||||
|
MkIORes a w => mab a w
|
||||||
|
pure = MkIORes
|
||||||
|
|
||||||
|
pfunc putStrLn uses (MkIORes MkUnit) : String -> IO Unit := `(s) => (w) => {
|
||||||
|
console.log(s)
|
||||||
|
return Prelude_MkIORes(null,Prelude_MkUnit,w)
|
||||||
|
}`
|
||||||
|
|
||||||
|
main : IO Unit
|
||||||
|
main = putStrLn "Hello, World!"
|
||||||
|
|||||||
1
playground/src/global.d.ts
vendored
1
playground/src/global.d.ts
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
declare module "*.css";
|
declare module "*.css";
|
||||||
export {};
|
export {};
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
29
playground/src/help.md
Normal file
29
playground/src/help.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Newt Playground
|
||||||
|
|
||||||
|
Newt is a dependent typed programming language that compiles to javascript. This playground embeds the newt compiler and a codemirror based editor.
|
||||||
|
|
||||||
|
The editor will typecheck the file with newt and render errors as the file is changed. The current file is saved to localStorage and will be restored if there is no data in the URL. Cmd-s or Ctrl-s will create a url embedding the file contents. There is a layout toggle for phone use.
|
||||||
|
|
||||||
|
## Tabs
|
||||||
|
|
||||||
|
**Output** - Displays the compiler output, which is also used to render errors and info annotations in the editor.
|
||||||
|
|
||||||
|
**JS** - Displays the javascript translation of the file
|
||||||
|
|
||||||
|
**Console** - Displays the console output from running the javascript
|
||||||
|
|
||||||
|
**Help** - Displays this help file
|
||||||
|
|
||||||
|
## Buttons
|
||||||
|
|
||||||
|
▶ Compile and run the current file in an iframe, console output is collected to the console tab.
|
||||||
|
|
||||||
|
📋 Embed the current file in the URL and copy to clipboard
|
||||||
|
|
||||||
|
↕ or ↔ Toggle vertical or horziontal layout (for mobile)
|
||||||
|
|
||||||
|
## Keyboard
|
||||||
|
|
||||||
|
*C-s or M-s* - Embed the current file in the URL and copy to clipboard
|
||||||
|
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { effect, signal } from "@preact/signals";
|
import { signal } from "@preact/signals";
|
||||||
import { Diagnostic } from "@codemirror/lint";
|
import { Diagnostic } from "@codemirror/lint";
|
||||||
import { useEffect, useRef, useState } from "preact/hooks";
|
import { useEffect, useRef, useState } from "preact/hooks";
|
||||||
import { h, render, VNode } from "preact";
|
import { h, render, VNode } from "preact";
|
||||||
@@ -15,6 +15,7 @@ import { CMEditor } from "./cmeditor.ts";
|
|||||||
import { deflate } from "./deflate.ts";
|
import { deflate } from "./deflate.ts";
|
||||||
import { inflate } from "./inflate.ts";
|
import { inflate } from "./inflate.ts";
|
||||||
import { IPC } from "./ipc.ts";
|
import { IPC } from "./ipc.ts";
|
||||||
|
import helpText from "./help.md?raw";
|
||||||
|
|
||||||
let topData: undefined | TopData;
|
let topData: undefined | TopData;
|
||||||
|
|
||||||
@@ -37,14 +38,14 @@ function md2nodes(md: string) {
|
|||||||
let list: VNode[] | undefined
|
let list: VNode[] | undefined
|
||||||
for (let line of md.split("\n")) {
|
for (let line of md.split("\n")) {
|
||||||
if (line.startsWith('- ')) {
|
if (line.startsWith('- ')) {
|
||||||
list = list ?? []
|
if (!list) {
|
||||||
|
list = []
|
||||||
|
rval.push(h('ul', {}, list))
|
||||||
|
}
|
||||||
list.push(h('li', {}, mdline2nodes(line.slice(2))))
|
list.push(h('li', {}, mdline2nodes(line.slice(2))))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (list) {
|
|
||||||
rval.push(h('ul', {}, list))
|
|
||||||
list = undefined
|
list = undefined
|
||||||
}
|
|
||||||
if (line.startsWith('# ')) {
|
if (line.startsWith('# ')) {
|
||||||
rval.push(h('h2', {}, mdline2nodes(line.slice(2))))
|
rval.push(h('h2', {}, mdline2nodes(line.slice(2))))
|
||||||
} else if (line.startsWith('## ')) {
|
} else if (line.startsWith('## ')) {
|
||||||
@@ -277,35 +278,7 @@ function Result() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Help() {
|
function Help() {
|
||||||
return h("div", { id: "help" },
|
return h("div", { id: "help" }, md2nodes(helpText))
|
||||||
md2nodes(`
|
|
||||||
# Newt Playground
|
|
||||||
|
|
||||||
The editor will typecheck the file with newt and render errors as the file is changed. The current file is saved to localStorage and will be restored if there is no data in the URL. Cmd-s / Ctrl-s will create a url embedding the file contents. There is a layout toggle for phone use.
|
|
||||||
|
|
||||||
## Tabs
|
|
||||||
|
|
||||||
**Output** - Displays the compiler output, which is also used to render errors and info annotations in the editor.
|
|
||||||
|
|
||||||
**JS** - Displays the javascript translation of the file
|
|
||||||
|
|
||||||
**Console** - Displays the console output from running the javascript
|
|
||||||
|
|
||||||
**Help** - Displays this help file
|
|
||||||
|
|
||||||
## Buttons
|
|
||||||
|
|
||||||
▶ Compile and run the current file in an iframe, console output is collected to the console tab.
|
|
||||||
|
|
||||||
📋 Embed the current file in the URL and copy to clipboard
|
|
||||||
|
|
||||||
↕ or ↔ Toggle vertical or horziontal layout (for mobile)
|
|
||||||
|
|
||||||
## Keyboard
|
|
||||||
|
|
||||||
*C-s or M-s* - Embed the current file in the URL and copy to clipboard
|
|
||||||
`)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Console() {
|
function Console() {
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ fcCol (MkFC file (l, c)) = c
|
|||||||
class HasFC a where
|
class HasFC a where
|
||||||
getFC : a -> FC
|
getFC : a -> FC
|
||||||
|
|
||||||
|
primNS : List String
|
||||||
|
primNS = ("Prim" :: Nil)
|
||||||
|
|
||||||
emptyFC : FC
|
emptyFC : FC
|
||||||
emptyFC = MkFC "" (0,0)
|
emptyFC = MkFC "" (0,0)
|
||||||
|
|||||||
@@ -1162,9 +1162,9 @@ buildLitCases ctx prob fc scnm scty = do
|
|||||||
-- If we lookupRaw "String", we could get different answers in different contexts.
|
-- If we lookupRaw "String", we could get different answers in different contexts.
|
||||||
-- maybe Hardwire this one
|
-- maybe Hardwire this one
|
||||||
stringType intType charType : QName
|
stringType intType charType : QName
|
||||||
stringType = QN ("Prim" :: Nil) "String"
|
stringType = QN primNS "String"
|
||||||
intType = QN ("Prim" :: Nil) "Int"
|
intType = QN primNS "Int"
|
||||||
charType = QN ("Prim" :: Nil) "Char"
|
charType = QN primNS "Char"
|
||||||
|
|
||||||
litTyName : Literal -> QName
|
litTyName : Literal -> QName
|
||||||
litTyName (LString str) = stringType
|
litTyName (LString str) = stringType
|
||||||
@@ -1213,6 +1213,8 @@ buildTree ctx prob@(MkProb ((MkClause fc constraints Nil expr) :: cs) ty) = do
|
|||||||
-- If we try on creation, we're looping at the moment, because of the possibility
|
-- If we try on creation, we're looping at the moment, because of the possibility
|
||||||
-- of Ord a -> Ord b -> Ord (a \x b). Need to cut earlier when solving or switch to
|
-- of Ord a -> Ord b -> Ord (a \x b). Need to cut earlier when solving or switch to
|
||||||
-- Idris method...
|
-- Idris method...
|
||||||
|
-- This is necessary for tests/InferenceIssue.newt
|
||||||
|
-- solveAutos below is the important part
|
||||||
scty' <- case scty' of
|
scty' <- case scty' of
|
||||||
(VMeta fc1 ix sp) => do
|
(VMeta fc1 ix sp) => do
|
||||||
meta <- lookupMeta ix
|
meta <- lookupMeta ix
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ import Lib.Syntax
|
|||||||
import Node
|
import Node
|
||||||
import Serialize
|
import Serialize
|
||||||
|
|
||||||
primNS : List String
|
|
||||||
primNS = ("Prim" :: Nil)
|
|
||||||
|
|
||||||
jsonTopContext : M Json
|
jsonTopContext : M Json
|
||||||
jsonTopContext = do
|
jsonTopContext = do
|
||||||
top <- getTop
|
top <- getTop
|
||||||
|
|||||||
Reference in New Issue
Block a user