all repos — min @ 2465db761b6bc7b668e881cce803048de678d445

A small but practical concatenative programming language.

fs module no longer imported.
h3rald h3rald@h3rald.com
Sun, 04 Aug 2024 12:07:17 +0200
commit

2465db761b6bc7b668e881cce803048de678d445

parent

f175852fe1999c01ed9dfd62f521b7d20e393da8

M minpkg/lib/min_fs.nimminpkg/lib/min_fs.nim

@@ -36,12 +36,12 @@ let vals = i.expect("'sym")

let s = vals[0] i.push s.getString.isHidden.newVal - def.symbol("fsize") do (i: In): + def.symbol("size") do (i: In): let vals = i.expect("'sym") let s = vals[0] i.push s.getString.getFileSize.newVal - def.symbol("fstats") do (i: In): + def.symbol("stats") do (i: In): let vals = i.expect("'sym") let s = vals[0] let fi = s.getString.getFileInfo

@@ -58,12 +58,12 @@ i.dset(info, "atime", fi.lastAccessTime.toUnix.newVal)

i.dset(info, "mtime", fi.lastWriteTime.toUnix.newVal) i.push info - def.symbol("ftype") do (i: In): + def.symbol("type") do (i: In): let vals = i.expect("'sym") let s = vals[0] i.push s.getString.getFileInfo.kind.filetype.newVal - def.symbol("fperms") do (i: In): + def.symbol("permissions") do (i: In): let vals = i.expect("'sym") let s = vals[0] i.push s.getString.getFilePermissions.unixPermissions.newVal

@@ -159,7 +159,7 @@ def.symbol("absolute-path?") do (i: In):

let vals = i.expect("'sym") i.push vals[0].getString.isAbsolute.newVal - def.symbol("fread") do (i: In): + def.symbol("read") do (i: In): let vals = i.expect("str") let file = vals[0].strVal var contents = ""

@@ -172,13 +172,13 @@ if contents == "":

contents = file.readFile i.push newVal(contents) - def.symbol("fwrite") do (i: In): + def.symbol("write") do (i: In): let vals = i.expect("str", "str") let a = vals[0] let b = vals[1] a.strVal.writeFile(b.strVal) - def.symbol("fappend") do (i: In): + def.symbol("append") do (i: In): let vals = i.expect("str", "str") let a = vals[0] let b = vals[1]
M next-release.mdnext-release.md

@@ -19,6 +19,12 @@ - **io** module: renamed **fread** and **read** to **fs.read**

- **io** module: renamed **fappend** to **fs.append** - **io** module: moved **print** to the **global** module. - **io** module: removed **newline** (use `"" puts!` instead). +- The **fs** module is no longer imported. +- **fs** module: renamed **fperms** to **fs.permissions** +- **fs** module: renamed **fsize** to **fs.size** +- **fs** module: renamed **fstats** to **fs.stats** +- **fs** module: renamed **ftype** to **fs.type** + ### New Features
M prelude.minprelude.min

@@ -1,7 +1,6 @@

; Imports 'dict import 'time import -'fs import 'sys import 'dstore import 'crypto import
M site/contents/learn-control-flow.mdsite/contents/learn-control-flow.md

@@ -72,12 +72,12 @@

. ls ( ( - (fsize) + (fs.size) (pop 0) ) try ) map 1 (+) reduce -This program calculates the size in bytes of all files included in the current directory. Because the {#link-operator||fs||fsize#} symbol throws an error if the argument provided is not a file (for example, if it is a directory), the `try` symbol is used to remove the error from the stack and push `0` on the stack instead. +This program calculates the size in bytes of all files included in the current directory. Because the {#link-operator||fs||size#} symbol throws an error if the argument provided is not a file (for example, if it is a directory), the `try` symbol is used to remove the error from the stack and push `0` on the stack instead. {#link-learn||shell||Shell#}
M site/contents/learn-definitions.mdsite/contents/learn-definitions.md

@@ -9,8 +9,8 @@ Being a concatenative language, min does not really need named parameters or variables: symbols just pop elements off the main stack in order, and that's normally enough. There is however one small problem with the traditional concatenative paradigm; consider the following program for example:

dup dup "\.zip$" match? - swap fsize 1000000 > and - swap mtime now 3600 - > + swap fs.size 1000000 > and + swap fs.mtime now 3600 - > This program takes a single string corresponding to a file path and returns true if it's a .zip file bigger than 1MB that was modified in the last hour. Sure, it is remarkable that no variables are needed for such a program, but it is not very readable: because no variables are used, it is often necessary to make copies of elements and push them to the end of the stack -- that's what the {#link-operator||stack||dup#} and {#link-operator||stack||swap#} are used for.

@@ -20,8 +20,8 @@ Consider the following program:

:filepath filepath "\.zip$" match? - filepath fsize 1000000 > - filepath mtime now 3600 - > + filepath fs.size 1000000 > + filepath fs.mtime now 3600 - > and and In this case, the `filepath` symbol is defined and then used on the following three lines, each of which defines a condition to be evaluated. The last line contains just two {#link-operator||global||and#} symbols necessary to compare the three conditions.
M site/contents/learn-quotations.mdsite/contents/learn-quotations.md

@@ -8,7 +8,7 @@ Quotations are the most important thing to understand in min. Besides being the data type used for lists, they are also used to delimit blocks of min code that is not going to be immediately executed.

Consider for example the following min code which returns all the files present in the current folder sorted by name: - . ls (ftype "file" ==) filter '> sort + . ls (fs.type "file" ==) filter '> sort The symbol {#link-operator||seq||filter#} takes two quotations as arguments -- the first quotation on the stack is applied to all the elements of the second quotation on the stack, to determine which elements of the second quotation will be part of the resulting quotation. This is an example of how quotations can be used both as lists and programs.

@@ -19,8 +19,8 @@ {{flist => ("file1.txt" "file2.txt" "file3.md" "file4.md")}}

1. The `.` symbol is pushed on the stack, and it is immediately evaluated to the full path to the current directory. 2. The `ls` symbol is pushed on the stack, it consumes the string already on the stack and returns a quotation containing all files and directories within the current directory. -3. The quotation `(ftype 'file ==)` is pushed on the stack. It is treated exactly like a list of data and it is not evaluated. -4. The `filter` symbol is pushed on the stack. This symbol takes two quotations as input, and applies the result of the first quotation on the stack (`(ftype "file" ==)`) to all elements of the second quotation of the stack (the list of files and directories), returning a new quotation containing only those elements of the second quotation on the stack that satisfy the result of the first quotation. In this case, it returns a new quotation containing only files. +3. The quotation `(fs.type 'file ==)` is pushed on the stack. It is treated exactly like a list of data and it is not evaluated. +4. The `filter` symbol is pushed on the stack. This symbol takes two quotations as input, and applies the result of the first quotation on the stack (`(fs.type "file" ==)`) to all elements of the second quotation of the stack (the list of files and directories), returning a new quotation containing only those elements of the second quotation on the stack that satisfy the result of the first quotation. In this case, it returns a new quotation containing only files. 5. `'>` is pushed on the stack. The `'` sigil can be used instead of the `quote` symbol to quote a single symbol, `>` in this case. In other words, it is instantly evaluated to the quotation `(>)`. 6. The symbol `sort` is pushed on the stack. This symbol, like `filter`, takes two quotations as input, and applies the first quotation to each element of the second quotation, effectively sorting each element of the second quotation using the predicate expressed by the first quotation. In this case, all files are sorted by name in ascending order.
M site/contents/reference-fs.mdsite/contents/reference-fs.md

@@ -37,20 +37,35 @@

{#op||filename||{{sl}}||{{s}}|| Returns the file name of path {{sl}}.#} -{#op||fperms||{{sl}}||{{i}}|| +{#op||hidden?||{{sl}}||{{b}}|| +Returns {{t}} if file/directory {{sl}} is hidden, {{f}} otherwise.#} + +{#op||join-path||{{q}}||{{s}}|| +Joins the strings contained in {{q}} with `/`.#} + +{#op||normalized-path||{{sl}}||{{s}}|| +Returns the normalized path to {{sl}}. #} + +{#op||mtime||{{sl}}||{{flt}}|| +Returns a timestamp corresponding to the time that file/directory {{sl}} was last modified.#} + +{#op||permissions||{{sl}}||{{i}}|| Returns the Unix permissions (expressed as a three-digit number) of file/directory {{sl}}.#} -{#op||fsize||{{sl}}||{{i}}|| +{#op||relative-path||{{sl1}} {{sl2}}||{{s}}|| +Returns the path of {{sl1}} relative to {{sl2}}. #} + +{#op||size||{{sl}}||{{i}}|| Returns the size in bytes of file/directory {{sl}}.#} -{#op||fstats||{{sl}}||{{d}}|| +{#op||stats||{{sl}}||{{d}}|| > Returns a dictionary {{d}} containing information on file/directory {{sl}}. > > %sidebar% > > Example > > > > Assuming that `min` is a file, the following: > > -> > `"min" fstats` +> > `"min" fs.stats` > > > > produces: > >

@@ -67,26 +82,11 @@ > > 1496584370.0 :atime

> > 1496583112.0 :mtime > > }#} -{#op||ftype||{{sl}}||{{s}}|| -Returns the type of file/directory {{sl}} (`"file"` or `"dir"`).#} - -{#op||hidden?||{{sl}}||{{b}}|| -Returns {{t}} if file/directory {{sl}} is hidden, {{f}} otherwise.#} - -{#op||join-path||{{q}}||{{s}}|| -Joins the strings contained in {{q}} with `/`.#} - -{#op||normalized-path||{{sl}}||{{s}}|| -Returns the normalized path to {{sl}}. #} - -{#op||mtime||{{sl}}||{{flt}}|| -Returns a timestamp corresponding to the time that file/directory {{sl}} was last modified.#} - -{#op||relative-path||{{sl1}} {{sl2}}||{{s}}|| -Returns the path of {{sl1}} relative to {{sl2}}. #} - {#op||symlink?||{{sl}}||{{b}}|| Returns {{t}} if the specified path {{sl}} exists and is a symbolic link. #} + +{#op||type||{{sl}}||{{s}}|| +Returns the type of file/directory {{sl}} (`"file"` or `"dir"`).#} {#op||unix-path||{{sl}}||{{s}}|| Converts all backslashes in {{sl}} to slashes. #}
M tasks/_helpers.mintasks/_helpers.min

@@ -1,1 +1,1 @@

- "min.yml" fread from-yaml :config ".env.yml" fread from-yaml :env ( symbol required ('sym :prog ==>) ( (prog which "" ==) ("$# is not available" (prog) =% io.error 1 exit) when ) ) ::+ "min.yml" fs.read from-yaml :config ".env.yml" fs.read from-yaml :env ( symbol required ('sym :prog ==>) ( (prog which "" ==) ("$# is not available" (prog) =% io.error 1 exit) when ) ) ::
M tasks/build.mintasks/build.min

@@ -1,1 +1,1 @@

-#!/usr/bin/env minsystemsystemsystem "_helpers" require :helpers 'helpers import ( symbol cz ('sym :stage 'sym :variant 'sym :target-os ==>) ( true :pack-result (stage "^(release-nopack|dev)$" match?) (false @pack-result) when "-d:release" :d-stage (stage "dev" ==) ("-d:dev" @d-stage) when " " :d-variant "min" :o-variant (variant length 0 >) ( "-d:$# " (variant) =% @d-variant "$#min" (variant) =% @o-variant ) when "nim" required "Building $# - $# (x64)" (o-variant target-os) =% io.notice! "" :musl "musl-gcc" which :musl-gcc (musl-gcc length 0 >) ("--gcc.exe:musl-gcc --gcc.linkerexe:musl-gcc" @musl) when "nim c $# -d:ssl -d:useOpenSsl3 $# --opt:size --cpu:amd64 --os:$# $#-o:$# min" (d-stage musl target-os d-variant o-variant) =% puts system stack.pop (pack-result) ( {} target-os "os" dset config "version" dget "version" dset o-variant "exe" dset pack ) when ) ) :: ;; Builds and packs a min executable. #|| Tasks ||# ( symbol guide (==>) ( "hastyscribe" required "Building - guide" io.notice! "hastyscribe Min_DeveloperGuide.md --field/version=$#" (version) =% system "cp Min_DeveloperGuide.htm site/output/guide.dev.html" system ) ) :: ;; Builds the developer guide. ( symbol site (==>) ( "hastysite" required "Building - site" io.notice! "cd site && hastysite build && cd .." system ) ) :: ;; Builds the min site. ( symbol pack (dict :vdata ==>) ( vdata "exe" dget :exe (vdata "os" dget "windows" ==) ("$#.exe" (exe) =% @exe) when "$exe:_v$version:_$os:_x64.zip" :fn fn vdata dpairs % ":" "" replace @fn "Compressing: $#" (fn) =% io.notice! (exe) => fn zip ) ) :: ;; Compresses a min executable. ( symbol vim (==>) ( config "version" dget :min-version "tasks/data/min.vim" fread :template timestamp "dd MMM YYYY" tformat :date min-symbols ("||" !=) filter " " join :symbols "min.vim" :out-file "Building - min.vim" io.notice! template ("date" date "version" min-version "symbols" symbols) =% out-file fwrite ) ) :: ;; Generates the min.vim file. ( symbol docs (==>) ( guide site ) ) :: ;; Generate the min development guide and site. ( symbol dev (==>) ("dev" "" os cz) ) :: ;; Builds min (dev version) on the current OS. ( symbol default (==>) ("release-nopack" "" os cz) ) :: ;; Builds min on the current OS. ( symbol linux (==>) ("" "" "linux" cz) ) :: ;; Builds min for Linux. ( symbol macosx (==>) ("" "" "macosx" cz) ) :: ;; Builds min for macOS. ( symbol windows (==>) ("" "" "windows" cz) ) :: ;; Builds min for Windows. +#!/usr/bin/env minsystemsystemsystem "_helpers" require :helpers 'helpers import ( symbol cz ('sym :stage 'sym :variant 'sym :target-os ==>) ( true :pack-result (stage "^(release-nopack|dev)$" match?) (false @pack-result) when "-d:release" :d-stage (stage "dev" ==) ("-d:dev" @d-stage) when " " :d-variant "min" :o-variant (variant length 0 >) ( "-d:$# " (variant) =% @d-variant "$#min" (variant) =% @o-variant ) when "nim" required "Building $# - $# (x64)" (o-variant target-os) =% io.notice! "" :musl "musl-gcc" which :musl-gcc (musl-gcc length 0 >) ("--gcc.exe:musl-gcc --gcc.linkerexe:musl-gcc" @musl) when "nim c $# -d:ssl -d:useOpenSsl3 $# --opt:size --cpu:amd64 --os:$# $#-o:$# min" (d-stage musl target-os d-variant o-variant) =% puts system stack.pop (pack-result) ( {} target-os "os" dset config "version" dget "version" dset o-variant "exe" dset pack ) when ) ) :: ;; Builds and packs a min executable. #|| Tasks ||# ( symbol guide (==>) ( "hastyscribe" required "Building - guide" io.notice! "hastyscribe Min_DeveloperGuide.md --field/version=$#" (version) =% system "cp Min_DeveloperGuide.htm site/output/guide.dev.html" system ) ) :: ;; Builds the developer guide. ( symbol site (==>) ( "hastysite" required "Building - site" io.notice! "cd site && hastysite build && cd .." system ) ) :: ;; Builds the min site. ( symbol pack (dict :vdata ==>) ( vdata "exe" dget :exe (vdata "os" dget "windows" ==) ("$#.exe" (exe) =% @exe) when "$exe:_v$version:_$os:_x64.zip" :fn fn vdata dpairs % ":" "" replace @fn "Compressing: $#" (fn) =% io.notice! (exe) => fn zip ) ) :: ;; Compresses a min executable. ( symbol vim (==>) ( config "version" dget :min-version "tasks/data/min.vim" fs.read :template timestamp "dd MMM YYYY" tformat :date min-symbols ("||" !=) filter " " join :symbols "min.vim" :out-file "Building - min.vim" io.notice! template ("date" date "version" min-version "symbols" symbols) =% out-file fs.write ) ) :: ;; Generates the min.vim file. ( symbol docs (==>) ( guide site ) ) :: ;; Generate the min development guide and site. ( symbol dev (==>) ("dev" "" os cz) ) :: ;; Builds min (dev version) on the current OS. ( symbol default (==>) ("release-nopack" "" os cz) ) :: ;; Builds min on the current OS. ( symbol linux (==>) ("" "" "linux" cz) ) :: ;; Builds min for Linux. ( symbol macosx (==>) ("" "" "macosx" cz) ) :: ;; Builds min for macOS. ( symbol windows (==>) ("" "" "windows" cz) ) :: ;; Builds min for Windows.
M tasks/github.mintasks/github.min

@@ -1,1 +1,1 @@

-#!/usr/bin/env min "_helpers" require :helpers 'helpers import "next-release.md" fread escape :release-body "tasks/data/draft-release.json" fread :draft-release-template config "version" dget :min-version env "github-token" dget :token draft-release-template ("version" min-version "body" release-body) =% :draft-release-body {} "application/vnd.github.v3+json" "Accept" dset "token $#" (token) =% "Authorization" dset :headers ( symbol handle-errors (dict :response ==>) ( response to-json "response.json" fwrite response "status" dget :status (status 300 >) ( response "body" dget from-json :body body "message" dget :message status string @status "Error $#: $#" (status message) =% io.error status int exit ) when ) ) :: ;; Handles HTTP errors. ( symbol gh-req (dict :data ==> dict|quot :result) ( data "endpoint" dget :endpoint "api" :subdomain (data 'subdomain dhas?) (data "subdomain" dget @subdomain) when "https://$#.github.com/repos/h3rald/min$#" (subdomain endpoint) =% :url {} url "url" dset data "method" dget "method" dset (data 'headers dhas?) (data "headers" dget "headers" dset) (headers "headers" dset) if (data 'body dhas?) (data "body" dget "body" dset) when request :response response "status" dget :status response "body" dget :body response handle-errors (body length 0 >) (body from-json) ({}) if @result ) ) :: ;; Execute a request using the Github API. ( symbol get-assets (dict :data ==> quot :result) ( data "id" dget :id {} "/releases/$#/assets" (id) =% "endpoint" dset "GET" "method" dset gh-req @result ) ) :: ;; Retrieve the assets from an existing Github release. ( symbol delete-assets (dict :config ==>) ( config get-assets :assets config "id" dget :id assets ("id" dget) map :assets-ids assets-ids ( :asset {} "/releases/assets/$#" (asset) =% "endpoint" dset "DELETE" "method" dset gh-req stack.pop ) foreach ) ) :: ;; Delete all assets from an existing Github release. #|| Tasks ||# ( symbol draft (==>) ( {} "/releases" "endpoint" dset "POST" "method" dset draft-release-body "body" dset gh-req "id" dget string :id ;; Save Release ID to min.yml config id "id" dset to-yaml "min.yml" fwrite "Draft release v$# ($#) created successfully" (min-version id) =% io.notice! ) ) :: ;; Creates a new draft release on Github. ( symbol update (==>) ( config "id" dget :id {} "/releases/$#" (id) =% "endpoint" dset "PATCH" "method" dset draft-release-body "body" dset gh-req "id" dget string :id "Draft release v$# ($#) updated successfully" (min-version id) =% io.notice! ) ) :: ;; Updates the text of the current draft Github release. ( symbol assets (==>) ( config get-assets =assets assets size :total "are" :verb (total 1 ==) ("is" @verb) when "There $# $# assets in release v$#" (verb total min-version) =% io.notice! assets ("name" dget () stack.cons "- $#" stack.swap % io.notice!) foreach ) ) :: ;; Retrieve a list of all the assets of the current draft Github release. ( symbol upload (==>) ( config "id" dget :id config delete-assets pwd ls ("\\.zip$" match?) filter ( filename :file "Uploading: $#" (file) =% io.notice! file fread :body headers "application/zip" "Content-Type" dset :asset-headers {} "/releases/$#/assets?name=$#" (id file) =% "endpoint" dset asset-headers "headers" dset "uploads" "subdomain" dset "POST" "method" dset body "body" dset gh-req stack.pop ) foreach ) ) :: ;; Uploads all assets to the current draft Github release, deleting any existing asset. +#!/usr/bin/env min "_helpers" require :helpers 'helpers import "next-release.md" fs.read escape :release-body "tasks/data/draft-release.json" fs.read :draft-release-template config "version" dget :min-version env "github-token" dget :token draft-release-template ("version" min-version "body" release-body) =% :draft-release-body {} "application/vnd.github.v3+json" "Accept" dset "token $#" (token) =% "Authorization" dset :headers ( symbol handle-errors (dict :response ==>) ( response to-json "response.json" fs.write response "status" dget :status (status 300 >) ( response "body" dget from-json :body body "message" dget :message status string @status "Error $#: $#" (status message) =% io.error status int exit ) when ) ) :: ;; Handles HTTP errors. ( symbol gh-req (dict :data ==> dict|quot :result) ( data "endpoint" dget :endpoint "api" :subdomain (data 'subdomain dhas?) (data "subdomain" dget @subdomain) when "https://$#.github.com/repos/h3rald/min$#" (subdomain endpoint) =% :url {} url "url" dset data "method" dget "method" dset (data 'headers dhas?) (data "headers" dget "headers" dset) (headers "headers" dset) if (data 'body dhas?) (data "body" dget "body" dset) when request :response response "status" dget :status response "body" dget :body response handle-errors (body length 0 >) (body from-json) ({}) if @result ) ) :: ;; Execute a request using the Github API. ( symbol get-assets (dict :data ==> quot :result) ( data "id" dget :id {} "/releases/$#/assets" (id) =% "endpoint" dset "GET" "method" dset gh-req @result ) ) :: ;; Retrieve the assets from an existing Github release. ( symbol delete-assets (dict :config ==>) ( config get-assets :assets config "id" dget :id assets ("id" dget) map :assets-ids assets-ids ( :asset {} "/releases/assets/$#" (asset) =% "endpoint" dset "DELETE" "method" dset gh-req stack.pop ) foreach ) ) :: ;; Delete all assets from an existing Github release. #|| Tasks ||# ( symbol draft (==>) ( {} "/releases" "endpoint" dset "POST" "method" dset draft-release-body "body" dset gh-req "id" dget string :id ;; Save Release ID to min.yml config id "id" dset to-yaml "min.yml" fs.write "Draft release v$# ($#) created successfully" (min-version id) =% io.notice! ) ) :: ;; Creates a new draft release on Github. ( symbol update (==>) ( config "id" dget :id {} "/releases/$#" (id) =% "endpoint" dset "PATCH" "method" dset draft-release-body "body" dset gh-req "id" dget string :id "Draft release v$# ($#) updated successfully" (min-version id) =% io.notice! ) ) :: ;; Updates the text of the current draft Github release. ( symbol assets (==>) ( config get-assets =assets assets size :total "are" :verb (total 1 ==) ("is" @verb) when "There $# $# assets in release v$#" (verb total min-version) =% io.notice! assets ("name" dget () stack.cons "- $#" stack.swap % io.notice!) foreach ) ) :: ;; Retrieve a list of all the assets of the current draft Github release. ( symbol upload (==>) ( config "id" dget :id config delete-assets pwd ls ("\\.zip$" match?) filter ( fs.filename :file "Uploading: $#" (file) =% io.notice! file fs.read :body headers "application/zip" "Content-Type" dset :asset-headers {} "/releases/$#/assets?name=$#" (id file) =% "endpoint" dset asset-headers "headers" dset "uploads" "subdomain" dset "POST" "method" dset body "body" dset gh-req stack.pop ) foreach ) ) :: ;; Uploads all assets to the current draft Github release, deleting any existing asset.
M tasks/h3rald.mintasks/h3rald.min

@@ -1,1 +1,1 @@

-#!/usr/bin/env minsystemsystem "_helpers" require :helpers 'helpers import config "version" dget :min-version "Min_DeveloperGuide.htm" :guide-file "../h3rald/assets/min/" guide-file suffix :h3rald-guide "../h3rald/contents/min.md" :h3rald-min-md "version:\\s+\\d+\\.\\d+\\.\\d+" :min-v-reg "version: $#" (min-version) =% :min-v-rep ( symbol update (==>) ( "Updating min Developer Guide and project on H3RALD.com..." io.notice! guide-file h3rald-guide cp h3rald-min-md fread min-v-reg min-v-rep replace :updated-contents updated-contents h3rald-min-md fwrite "Done." io.notice! ) ) :: ;; Updates the min Developer Guide and project page on H3RALD.com ( symbol build (==>) ( "git" required "hastysite" required "Pulling content and rebuilding H3RALD.com web site..." io.notice! ;; Assuming min and h3rald are siblings parent-dir cd "h3rald" cd "git pull" system "hastysite build" system parent-dir cd "min" cd ) ) :: ;; Builds H3RALD.com web site +#!/usr/bin/env minsystemsystem "_helpers" require :helpers 'helpers import config "version" dget :min-version "Min_DeveloperGuide.htm" :guide-file "../h3rald/assets/min/" guide-file suffix :h3rald-guide "../h3rald/contents/min.md" :h3rald-min-md "version:\\s+\\d+\\.\\d+\\.\\d+" :min-v-reg "version: $#" (min-version) =% :min-v-rep ( symbol update (==>) ( "Updating min Developer Guide and project on H3RALD.com..." io.notice! guide-file h3rald-guide cp h3rald-min-md fs.read min-v-reg min-v-rep replace :updated-contents updated-contents h3rald-min-md fs.write "Done." io.notice! ) ) :: ;; Updates the min Developer Guide and project page on H3RALD.com ( symbol build (==>) ( "git" required "hastysite" required "Pulling content and rebuilding H3RALD.com web site..." io.notice! ;; Assuming min and h3rald are siblings parent-dir cd "h3rald" cd "git pull" system "hastysite build" system parent-dir cd "min" cd ) ) :: ;; Builds H3RALD.com web site
M tasks/help.mintasks/help.min

@@ -1,1 +1,1 @@

-"tasks/data/doc-snippets.json" fread from-json :snippets "site/contents" ls ("reference-" match?) filter :src-files "(?sm)\\{#op\\|\\|([^|]+)\\|\\|([^|]+)\\|\\|([^|]+)\\|\\|(.+?)#\\}" :op-regex "(?sm)\\{#sig\\|\\|([^|]+)\\|\\|([^#]+)#\\}" :sig-regex "(?sm)\\{#alias\\|\\|([^|]+)\\|\\|([^#]+)#\\}" :alias-regex "(?sm)\\{\\{([^}]+)\\}\\}" :snippet-regex "(?sm)\\>( \\>)*" :block-regex "(?sm)%([^%]+)%" :title-regex "(?sm)\\{@[^@]+@\\}" :incl-regex "(?sm)`([^`]+)`" :code-regex ( symbol fix-name (str :s ==> str :result) ( s "&excl;" (stack.pop "!") replace-apply "&quot;" (stack.pop "\"") replace-apply "&#124;" (stack.pop "|") replace-apply "\\[" (stack.pop "") replace-apply "\\]" (stack.pop "") replace-apply "\\(class:kwd\\)" (stack.pop "") replace-apply "&gt;" (stack.pop ">") replace-apply "&lt;" (stack.pop "<") replace-apply "&apos;" (stack.pop "'") replace-apply "&ast;" (stack.pop "*") replace-apply @result ) ) :: ;; Fixes names with special characters ( symbol process-block-markup (str :s ==> str :result) ( s block-regex (stack.pop "") replace-apply title-regex (stack.pop "") replace-apply incl-regex (stack.pop "") replace-apply code-regex (1 get) replace-apply @result ) ) :: ;; Simplify block-level markup ( symbol process-snippets (str :s ==> str :result) ( s snippet-regex ( 1 get :id snippets id dget ) replace-apply @result ) ) :: ;; Resolves documentation snippets. ( symbol process (str :s ==> str :result) ( s process-snippets process-block-markup strip @result ) ) :: ;; Processes documentation snippets and markup. ( symbol process-op (quot :matches ==> dict :data) ( {} matches 1 get process fix-name "name" dset matches 2 get process fix-name :input matches 3 get process fix-name :output "$# ==> $#" (input output) =% "signature" dset matches 4 get process "description" dset "symbol" "kind" dset @data ) ) :: ;; Processes operator reference documentation. ( symbol process-alias (quot :matches ==> dict :data) ( {} matches 1 get process fix-name "name" dset matches 2 get :ref "See $#" (ref) =% "description" dset "symbol" "kind" dset @data ) ) :: ;; Processes alias reference documentation. ( symbol process-sig (quot :matches ==> dict :data) ( {} matches 1 get process fix-name "name" dset matches 2 get :ref "See $#" (ref) =% "description" dset "sigil" "kind" dset @data ) ) :: ;; Processes sigil reference documentation. ( symbol default (==>) ( {} :ref-dict {} :op-dict {} :sig-dict src-files ( :file file "reference-([a-z]+)\\.md" search 1 get :mod-id "Processing: $#" (mod-id) =% io.notice! file fread :contents contents op-regex search-all ( process-op :op op "name" dget :op-name op mod-id 'module dset @op op-dict op op-name dset @op-dict ) foreach contents alias-regex search-all ( process-alias :alias alias "name" dget :alias-name alias mod-id 'module dset @alias op-dict alias alias-name dset @op-dict ) foreach contents sig-regex search-all ( process-sig :sig sig "name" dget :sig-name sig mod-id 'module dset @sig sig-dict sig sig-name dset @sig-dict ) foreach ref-dict op-dict "symbols" dset sig-dict "sigils" dset @ref-dict ) foreach "Writing help.json" io.notice! ref-dict to-json "help.json" fwrite ) ) :: ;; Builds the reference help JSON sources. +"tasks/data/doc-snippets.json" fs.read from-json :snippets "site/contents" ls ("reference-" match?) filter :src-files "(?sm)\\{#op\\|\\|([^|]+)\\|\\|([^|]+)\\|\\|([^|]+)\\|\\|(.+?)#\\}" :op-regex "(?sm)\\{#sig\\|\\|([^|]+)\\|\\|([^#]+)#\\}" :sig-regex "(?sm)\\{#alias\\|\\|([^|]+)\\|\\|([^#]+)#\\}" :alias-regex "(?sm)\\{\\{([^}]+)\\}\\}" :snippet-regex "(?sm)\\>( \\>)*" :block-regex "(?sm)%([^%]+)%" :title-regex "(?sm)\\{@[^@]+@\\}" :incl-regex "(?sm)`([^`]+)`" :code-regex ( symbol fix-name (str :s ==> str :result) ( s "&excl;" (stack.pop "!") replace-apply "&quot;" (stack.pop "\"") replace-apply "&#124;" (stack.pop "|") replace-apply "\\[" (stack.pop "") replace-apply "\\]" (stack.pop "") replace-apply "\\(class:kwd\\)" (stack.pop "") replace-apply "&gt;" (stack.pop ">") replace-apply "&lt;" (stack.pop "<") replace-apply "&apos;" (stack.pop "'") replace-apply "&ast;" (stack.pop "*") replace-apply @result ) ) :: ;; Fixes names with special characters ( symbol process-block-markup (str :s ==> str :result) ( s block-regex (stack.pop "") replace-apply title-regex (stack.pop "") replace-apply incl-regex (stack.pop "") replace-apply code-regex (1 get) replace-apply @result ) ) :: ;; Simplify block-level markup ( symbol process-snippets (str :s ==> str :result) ( s snippet-regex ( 1 get :id snippets id dget ) replace-apply @result ) ) :: ;; Resolves documentation snippets. ( symbol process (str :s ==> str :result) ( s process-snippets process-block-markup strip @result ) ) :: ;; Processes documentation snippets and markup. ( symbol process-op (quot :matches ==> dict :data) ( {} matches 1 get process fix-name "name" dset matches 2 get process fix-name :input matches 3 get process fix-name :output "$# ==> $#" (input output) =% "signature" dset matches 4 get process "description" dset "symbol" "kind" dset @data ) ) :: ;; Processes operator reference documentation. ( symbol process-alias (quot :matches ==> dict :data) ( {} matches 1 get process fix-name "name" dset matches 2 get :ref "See $#" (ref) =% "description" dset "symbol" "kind" dset @data ) ) :: ;; Processes alias reference documentation. ( symbol process-sig (quot :matches ==> dict :data) ( {} matches 1 get process fix-name "name" dset matches 2 get :ref "See $#" (ref) =% "description" dset "sigil" "kind" dset @data ) ) :: ;; Processes sigil reference documentation. ( symbol default (==>) ( {} :ref-dict {} :op-dict {} :sig-dict src-files ( :file file "reference-([a-z]+)\\.md" search 1 get :mod-id "Processing: $#" (mod-id) =% io.notice! file fs.read :contents contents op-regex search-all ( process-op :op op "name" dget :op-name op mod-id 'module dset @op op-dict op op-name dset @op-dict ) foreach contents alias-regex search-all ( process-alias :alias alias "name" dget :alias-name alias mod-id 'module dset @alias op-dict alias alias-name dset @op-dict ) foreach contents sig-regex search-all ( process-sig :sig sig "name" dget :sig-name sig mod-id 'module dset @sig sig-dict sig sig-name dset @sig-dict ) foreach ref-dict op-dict "symbols" dset sig-dict "sigils" dset @ref-dict ) foreach "Writing help.json" io.notice! ref-dict to-json "help.json" fs.write ) ) :: ;; Builds the reference help JSON sources.
M tasks/version.mintasks/version.min

@@ -4,9 +4,9 @@ "min.yml" :yaml-cfg

"min.nimble" :nimble-cfg "site/settings.json" :json-site-cfg -yaml-cfg fread from-yaml :config +yaml-cfg fs.read from-yaml :config config "version" dget :old-version -nimble-cfg fread :nimble-data +nimble-cfg fs.read :nimble-data (

@@ -14,7 +14,7 @@ symbol update-yaml-config

('sym :new-version ==>) ( config new-version "version" dset @config - config to-yaml yaml-cfg fwrite + config to-yaml yaml-cfg fs.write ) ) :: ;; Sets the version in the min.yml file to new-version.

@@ -23,9 +23,9 @@ (

symbol update-site-config ('sym :new-version ==>) ( - json-site-cfg fread from-json :site-config + json-site-cfg fs.read from-json :site-config site-config new-version "version" dset @site-config - site-config to-json json-site-cfg fwrite + site-config to-json json-site-cfg fs.write ) ) :: ;; Updates the version of the web site to new-version.

@@ -37,7 +37,7 @@ (

"(version\\s+=\\s*)([^\\s]+)(\\s*)" :version-regexp nimble-data version-regexp (stack.dup 1 get :start 3 get :end "$#\"$#\"$#" (start new-version end) =%) replace-apply @nimble-data - nimble-data nimble-cfg fwrite + nimble-data nimble-cfg fs.write ) ) :: ;; Updates the version in the nimble file to new-version.
M tests/fs.mintests/fs.min

@@ -2,48 +2,47 @@ 'min-test require :test

;;; "fs" test.describe + "TEST" "test.txt" fs.write + + ("test.txt" fs.size 4 ==) test.assert - "TEST" "test.txt" fwrite - - ("test.txt" fsize 4 ==) test.assert + ("test.txt" fs.permissions 644 >=) test.assert - ("test.txt" fperms 644 >=) test.assert + ("test.txt" fs.type "file" ==) test.assert - ("test.txt" ftype "file" ==) test.assert + ("test.txt" fs.hidden? false ==) test.assert - ("test.txt" hidden? false ==) test.assert + ("test.txt" fs.stats 'type dget "file" ==) test.assert - ("test.txt" fstats 'type dget "file" ==) test.assert + ("tests" fs.dir?) test.assert - ("tests" dir?) test.assert + ("tests" fs.exists?) test.assert - ("tests" exists?) test.assert + ("tests/fs.min" fs.file?) test.assert - ("tests/fs.min" file?) test.assert + (("a" "b" "c") fs.join-path "a/b/c" ==) test.assert - (("a" "b" "c") join-path "a/b/c" ==) test.assert + ("/home/h3rald" fs.windows-path "\\home\\h3rald" ==) test.assert - ("/home/h3rald" windows-path "\\home\\h3rald" ==) test.assert + ("/home/h3rald" fs.absolute-path?) test.assert - ("/home/h3rald" absolute-path?) test.assert + ("tests/sys.min" fs.expand-filename fs.unix-path pwd "/tests/sys.min" suffix fs.unix-path ==) test.assert - ("tests/sys.min" expand-filename unix-path pwd "/tests/sys.min" suffix unix-path ==) test.assert + ("./../tests" fs.normalized-path fs.unix-path "../tests" ==) test.assert - ("./../tests" normalized-path unix-path "../tests" ==) test.assert + ((pwd "tests/global.min") => fs.join-path pwd fs.relative-path fs.unix-path "tests/global.min" ==) test.assert - ((pwd "tests/global.min") => join-path pwd relative-path unix-path "tests/global.min" ==) test.assert + ("tests/global.min" fs.absolute-path fs.unix-path (pwd "tests/global.min") => fs.join-path fs.unix-path ==) test.assert - ("tests/global.min" absolute-path unix-path (pwd "tests/global.min") => join-path unix-path ==) test.assert + ("./test" fs.absolute-path? not) test.assert - ("./test" absolute-path? not) test.assert + ("c:/windows" fs.windows-path "c:\\windows" ==) test.assert - ("c:/windows" windows-path "c:\\windows" ==) test.assert + ("TEST" "test.txt" fs.write + "test.txt" fs.read "TEST" ==) test.assert - ("TEST" "test.txt" fwrite - "test.txt" fread "TEST" ==) test.assert - - (" - TEST" "test.txt" fappend - "test.txt" fread "TEST - TEST" ==) test.assert + (" - TEST" "test.txt" fs.append + "test.txt" fs.read "TEST - TEST" ==) test.assert test.report stack.clear
M tests/global.mintests/global.min

@@ -39,10 +39,10 @@ (symbols "five" in? false ==) test.assert

("3 4 +" eval 7 ==) test.assert - ("2 2 +" "tests/testload.min" fwrite 'testload load 4 ==) test.assert + ("2 2 +" "tests/testload.min" fs.write 'testload load 4 ==) test.assert "tests/testload.min" rm - ("2 :two 3 :three" "tests/testrequire.min" fwrite 'testrequire require :tm tm.two tm.three + 5 ==) test.assert + ("2 :two 3 :three" "tests/testrequire.min" fs.write 'testrequire require :tm tm.two tm.three + 5 ==) test.assert "tests/testrequire.min" rm (2 quote (2) ==) test.assert
M tests/http.mintests/http.min

@@ -8,7 +8,7 @@ "https://$1" (host) => % :url

("$1/get" (url) => % get-content from-json "headers" dget "user-agent" dget "min http-module/$1" (version) => % ==) test.assert - ("$1/get?test=Hello!" (url) => % "tests/test1.json" :file file download file fread from-json "args" dget "test" dget "Hello!" ==) test.assert + ("$1/get?test=Hello!" (url) => % "tests/test1.json" :file file download file fs.read from-json "args" dget "test" dget "Hello!" ==) test.assert "tests/test1.json" rm (
M tests/sys.mintests/sys.min

@@ -3,27 +3,27 @@ ;;;

"sys" test.describe - ("dir1" mkdir "dir1" dir?) test.assert + ("dir1" mkdir "dir1" fs.dir?) test.assert - ("dir1" "dir2" mv "dir2" dir?) test.assert + ("dir1" "dir2" mv "dir2" fs.dir?) test.assert - ("dir1" dir? false ==) test.assert + ("dir1" fs.dir? false ==) test.assert - ("dir2" "dir1" cp "dir1" dir?) test.assert + ("dir2" "dir1" cp "dir1" fs.dir?) test.assert - ("..." "dir1/test.txt" fwrite "dir1/test.txt" file?) test.assert + ("..." "dir1/test.txt" fs.write "dir1/test.txt" fs.file?) test.assert - ("dir1/test.txt" "dir2" mv "dir2/test.txt" file?) test.assert + ("dir1/test.txt" "dir2" mv "dir2/test.txt" fs.file?) test.assert - ("dir1/test.txt" file? false ==) test.assert + ("dir1/test.txt" fs.file? false ==) test.assert - ("dir2/test.txt" "dir1" cp "dir1/test.txt" file?) test.assert + ("dir2/test.txt" "dir1" cp "dir1/test.txt" fs.file?) test.assert - ('dir1 ls 'filename map ("test.txt") ==) test.assert + ('dir1 ls 'fs.filename map ("test.txt") ==) test.assert - ('dir2 ls 'dirname map ("dir2") ==) test.assert + ('dir2 ls 'fs.dirname map ("dir2") ==) test.assert - ('dir1 rmdir 'dir2 rmdir 'dir1 dir? 'dir2 dir? or false ==) test.assert + ('dir1 rmdir 'dir2 rmdir 'dir1 fs.dir? 'dir2 fs.dir? or false ==) test.assert ("systest" mkdir pwd ls (pwd "systest") => "/" join in?) test.assert

@@ -42,19 +42,19 @@ (os length 0 >) test.assert

(cpu length 0 >) test.assert - ("TEST" "test.txt" fwrite "test.txt" file?) test.assert + ("TEST" "test.txt" fs.write "test.txt" fs.file?) test.assert - ("test.txt" "test2.txt" cp "test2.txt" file?) test.assert + ("test.txt" "test2.txt" cp "test2.txt" fs.file?) test.assert - ("test.txt" "test1.txt" mv "test1.txt" file?) test.assert + ("test.txt" "test1.txt" mv "test1.txt" fs.file?) test.assert ("test2.txt" rm "test1.txt" rm pwd ls (pwd "test1.txt") => "/" join in? :t1 pwd ls "test2" in? t1 and false ==) test.assert ("systest" cd - "TEST" "test.txt" fwrite - "TEST1" "test1.txt" fwrite - "TEST2" "test2.txt" fwrite - "TEST3" "test3.txt" fwrite + "TEST" "test.txt" fs.write + "TEST1" "test1.txt" fs.write + "TEST2" "test2.txt" fs.write + "TEST3" "test3.txt" fs.write pwd ls "test.zip" zip pwd ls (pwd "test.zip") => "/" join in?) test.assert ("test.zip" "extracted" unzip "extracted" ls "extracted/test1.txt" in?) test.assert