From f9279bb255097ddace2fb658d7149b4a6631bd2c Mon Sep 17 00:00:00 2001 From: Steve Dunham Date: Sat, 18 Jan 2025 14:48:29 -0800 Subject: [PATCH] Use null for erased values to aid serialization --- newt/Prelude.newt | 34 +++++++++++++++++----------------- port/Data/IORef.newt | 6 +++--- port/Lib/Compile.newt | 2 +- port/Node.newt | 12 ++++++------ scripts/stats.py | 15 +++++++++++++++ src/Lib/Compile.idr | 2 +- 6 files changed, 43 insertions(+), 28 deletions(-) create mode 100644 scripts/stats.py diff --git a/newt/Prelude.newt b/newt/Prelude.newt index d04ff82..d0081aa 100644 --- a/newt/Prelude.newt +++ b/newt/Prelude.newt @@ -284,7 +284,7 @@ pfunc aget : {0 a : U} -> Array a -> Int -> a := `(a, arr, ix) => arr[ix]` pfunc aempty : {0 a : U} -> Unit -> Array a := `() => []` pfunc arrayToList uses (Nil _::_) : {0 a} → Array a → List a := `(a,arr) => { - let rval = Nil(a) + let rval = Nil(null) for (let i = arr.length - 1;i >= 0; i--) { rval = _$3A$3A_(a, arr[i], rval) } @@ -294,7 +294,7 @@ pfunc arrayToList uses (Nil _::_) : {0 a} → Array a → List a := `(a,arr) => -- for now I'll run this in JS -pfunc lines uses (arrayToList) : String → List String := `(s) => arrayToList(undefined,s.split('\n'))` +pfunc lines uses (arrayToList) : String → List String := `(s) => arrayToList(null,s.split('\n'))` pfunc p_strHead : (s : String) -> Char := `(s) => s[0]` pfunc p_strTail : (s : String) -> String := `(s) => s[0]` @@ -302,9 +302,9 @@ pfunc p_strTail : (s : String) -> String := `(s) => s[0]` pfunc trim : String -> String := `s => s.trim()` pfunc split uses (Nil _::_) : String -> String -> List String := `(s, by) => { let parts = s.split(by) - let rval = Nil(String) + let rval = Nil(null) parts.reverse() - parts.forEach(p => { rval = _$3A$3A_(undefined, p, rval) }) + parts.forEach(p => { rval = _$3A$3A_(null, p, rval) }) return rval }` @@ -329,7 +329,7 @@ pfunc intToNat uses (Z S) : Int -> Nat := `(n) => { -pfunc fastConcat uses (listToArray) : List String → String := `(xs) => listToArray(undefined, xs).join('')` +pfunc fastConcat uses (listToArray) : List String → String := `(xs) => listToArray(null, xs).join('')` pfunc replicate uses (natToInt) : Nat -> Char → String := `(n,c) => c.repeat(natToInt(n))` -- I don't want to use an empty type because it would be a proof of void @@ -379,7 +379,7 @@ instance HasIO IO where pfunc primPutStrLn uses (MkIORes MkUnit) : String -> IO Unit := `(s) => (w) => { console.log(s) - return MkIORes(undefined,MkUnit,w) + return MkIORes(null,MkUnit,w) }` putStrLn : ∀ io. {{HasIO io}} -> String -> io Unit @@ -401,8 +401,8 @@ pfunc chr : Int → Char := `(c) => String.fromCharCode(c)` pfunc unpack uses (Nil _::_) : String -> List Char := `(s) => { - let acc = Nil(undefined) - for (let i = s.length - 1; 0 <= i; i--) acc = _$3A$3A_(undefined, s[i], acc) + let acc = Nil(null) + for (let i = s.length - 1; 0 <= i; i--) acc = _$3A$3A_(null, s[i], acc) return acc }` @@ -418,7 +418,7 @@ pfunc pack : List Char → String := `(cs) => { pfunc debugStr uses (natToInt listToArray) : ∀ a. a → String := `(_, obj) => { const go = (obj) => { - if (obj === undefined) return "_" + if (obj === null) return "_" if (typeof obj == 'bigint') return ''+obj if (obj.tag === '_,_') { let rval = '(' @@ -429,7 +429,7 @@ pfunc debugStr uses (natToInt listToArray) : ∀ a. a → String := `(_, obj) => return rval + go(obj) + ')' } if (obj?.tag === '_::_' || obj?.tag === 'Nil') { - let stuff = listToArray(undefined,obj) + let stuff = listToArray(null,obj) return '['+(stuff.map(go).join(', '))+']' } if (obj instanceof Array) { @@ -620,20 +620,20 @@ instance Div Double where x / y = divDouble x y ptype IOArray : U → U pfunc newArray uses (MkIORes) : ∀ a. Int → a → IO (IOArray a) := - `(_, n, v) => (w) => MkIORes(undefined,Array(n).fill(v),w)` -pfunc arrayGet : ∀ a. IOArray a → Int → IO a := `(_, arr, ix) => w => MkIORes(undefined, arr[ix], w)` + `(_, n, v) => (w) => MkIORes(null,Array(n).fill(v),w)` +pfunc arrayGet : ∀ a. IOArray a → Int → IO a := `(_, arr, ix) => w => MkIORes(null, arr[ix], w)` pfunc arraySet uses (MkUnit) : ∀ a. IOArray a → Int → a → IO Unit := `(_, arr, ix, v) => w => { arr[ix] = v - return MkIORes(undefined, MkUnit, w) + return MkIORes(null, MkUnit, w) }` -pfunc arraySize uses (MkIORes) : ∀ a. IOArray a → IO Int := `(_, arr) => w => MkIORes(undefined, arr.length, w)` +pfunc arraySize uses (MkIORes) : ∀ a. IOArray a → IO Int := `(_, arr) => w => MkIORes(null, arr.length, w)` pfunc ioArrayToList uses (Nil _::_ MkIORes) : {0 a} → IOArray a → IO (List a) := `(a,arr) => w => { - let rval = Nil(a) + let rval = Nil(null) for (let i = arr.length - 1;i >= 0; i--) { rval = _$3A$3A_(a, arr[i], rval) } - return MkIORes(undefined, rval, w) + return MkIORes(null, rval, w) }` pfunc listToIOArray uses (MkIORes) : {0 a} → List a → IO (Array a) := `(a,list) => w => { @@ -642,7 +642,7 @@ pfunc listToIOArray uses (MkIORes) : {0 a} → List a → IO (Array a) := `(a,li rval.push(list.h1) list = list.h2 } - return MkIORes(undefined,rval,w) + return MkIORes(null,rval,w) }` class Cast a b where diff --git a/port/Data/IORef.newt b/port/Data/IORef.newt index 08014ed..892f059 100644 --- a/port/Data/IORef.newt +++ b/port/Data/IORef.newt @@ -5,11 +5,11 @@ import Prelude -- We should test this at some point ptype IORef : U → U -pfunc primNewIORef uses (MkIORes MkUnit) : ∀ a. a → IO (IORef a) := `(_, a) => (w) => MkIORes(undefined, [a], w)` -pfunc primReadIORef uses (MkIORes MkUnit) : ∀ a. IORef a → IO a := `(_, ref) => (w) => MkIORes(undefined, ref[0], w)` +pfunc primNewIORef uses (MkIORes MkUnit) : ∀ a. a → IO (IORef a) := `(_, a) => (w) => MkIORes(null, [a], w)` +pfunc primReadIORef uses (MkIORes MkUnit) : ∀ a. IORef a → IO a := `(_, ref) => (w) => MkIORes(null, ref[0], w)` pfunc primWriteIORef uses (MkIORes MkUnit) : ∀ a. IORef a → a → IO Unit := `(_, ref, a) => (w) => { ref[0] = a - return MkIORes(undefined,MkUnit,w) + return MkIORes(null,MkUnit,w) }` newIORef : ∀ io a. {{HasIO io}} → a → io (IORef a) diff --git a/port/Lib/Compile.newt b/port/Lib/Compile.newt index 2b4f83b..d2d8930 100644 --- a/port/Lib/Compile.newt +++ b/port/Lib/Compile.newt @@ -236,7 +236,7 @@ expToDoc (Apply x xs) = expToDoc x ++ text "(" ++ nest 2 (commaSep (map expToDoc expToDoc (Var nm) = jsIdent nm expToDoc (JLam nms (JReturn exp)) = text "(" <+> commaSep (map jsIdent nms) <+> text ") =>" <+> text "(" ++ expToDoc exp ++ text ")" expToDoc (JLam nms body) = text "(" <+> commaSep (map jsIdent nms) <+> text ") =>" <+> bracket "{" (stmtToDoc body) "}" -expToDoc JUndefined = text "undefined" +expToDoc JUndefined = text "null" expToDoc (Index obj ix) = expToDoc obj ++ text "(" ++ expToDoc ix ++ text " :: Nil)" expToDoc (Dot obj nm) = expToDoc obj ++ text "." ++ jsIdent nm diff --git a/port/Node.newt b/port/Node.newt index e100881..b6926e0 100644 --- a/port/Node.newt +++ b/port/Node.newt @@ -8,12 +8,12 @@ pfunc readFile uses (fs MkIORes Left Right) : (fn : String) -> IO (Either String let result try { let content = fs.readFileSync(fn, 'utf8') - result = Right(undefined, undefined, content) + result = Right(null, null, content) } catch (e) { let err = ""+e - result = Left(undefined, undefined, e) + result = Left(null, null, e) } - return MkIORes(undefined, result, w) + return MkIORes(null, result, w) }` -- I wonder if I should automatically `uses` the constructors in the types @@ -21,12 +21,12 @@ pfunc writeFile uses (fs MkIORes MkUnit) : String → String → IO (Either Stri let result try { fs.writeFileSync(fn, content, 'utf8') - result = Right(undefined, undefined, MkUnit) + result = Right(null, null, MkUnit) } catch (e) { let err = ""+e - result = Left(undefined, undefined, e) + result = Left(null, null, e) } - return MkIORes(undefined, result, w) + return MkIORes(null, result, w) }` -- maybe System.exit or something, like the original putStrLn msg >> exitFailure diff --git a/scripts/stats.py b/scripts/stats.py new file mode 100644 index 0000000..fe72c54 --- /dev/null +++ b/scripts/stats.py @@ -0,0 +1,15 @@ +stats = {} +acc = '' +name = '' +for line in open('newt.js'): + if line.startswith('const'): + if name: stats[name] = len(acc) + acc = line + name = line.split()[1] + else: + acc += line +if name: stats[name] = len(acc) + +sorted_stats = sorted(((v, k) for k, v in stats.items())) +for value, key in sorted_stats: + print(value, key) diff --git a/src/Lib/Compile.idr b/src/Lib/Compile.idr index ed67b04..20ef115 100644 --- a/src/Lib/Compile.idr +++ b/src/Lib/Compile.idr @@ -232,7 +232,7 @@ expToDoc (Apply x xs) = expToDoc x ++ text "(" ++ nest 2 (commaSep (map expToDoc expToDoc (Var nm) = jsIdent nm expToDoc (JLam nms (JReturn exp)) = text "(" <+> commaSep (map jsIdent nms) <+> text ") =>" <+> text "(" ++ expToDoc exp ++ text ")" expToDoc (JLam nms body) = text "(" <+> commaSep (map jsIdent nms) <+> text ") =>" <+> bracket "{" (stmtToDoc body) "}" -expToDoc JUndefined = text "undefined" +expToDoc JUndefined = text "null" expToDoc (Index obj ix) = expToDoc obj ++ text "[" ++ expToDoc ix ++ text "]" expToDoc (Dot obj nm) = expToDoc obj ++ text "." ++ jsIdent nm