@ianlangs/mathscript 1.2.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/mpm/mpm.js ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs"
3
+ import path from "path"
4
+ import https from "https"
5
+ import { execSync } from "child_process"
6
+
7
+ const args = process.argv.slice(2)
8
+ const CWD = process.cwd()
9
+ const MODULES_DIR = path.join(CWD, "ms_modules")
10
+ const DEFAULT_REPO = "https://ianlangs.github.io/mpm-ms/"
11
+
12
+ function ensureDir(dir) {
13
+ if (!fs.existsSync(dir)) {
14
+ fs.mkdirSync(dir, { recursive: true })
15
+ }
16
+ }
17
+
18
+ function download(url, dest) {
19
+ return new Promise((resolve, reject) => {
20
+ const file = fs.createWriteStream(dest)
21
+ https.get(url, res => {
22
+ if (res.statusCode !== 200) {
23
+ reject("HTTP " + res.statusCode)
24
+ return
25
+ }
26
+ res.pipe(file)
27
+ file.on("finish", () => {
28
+ file.close()
29
+ resolve()
30
+ })
31
+ }).on("error", err => {
32
+ fs.unlinkSync(dest)
33
+ reject(err)
34
+ })
35
+ })
36
+ }
37
+
38
+ function installFromDefault(pkg) {
39
+ const url = DEFAULT_REPO + pkg + ".ms"
40
+ const dest = path.join(MODULES_DIR, pkg + ".ms")
41
+ console.log("Installing", pkg, "from", url)
42
+ return download(url, dest)
43
+ }
44
+
45
+ function installFromCustom(url) {
46
+ const name = url.split("/").pop()
47
+ const dest = path.join(MODULES_DIR, name)
48
+ console.log("Installing", name, "from", url)
49
+ return download(url, dest)
50
+ }
51
+
52
+ function installFromNpm(pkg) {
53
+ console.log("Installing from npm:", pkg)
54
+ execSync("npm install " + pkg, { stdio: "inherit" })
55
+ }
56
+
57
+ function usage() {
58
+ console.log(`
59
+ mpm - MS Package Manager
60
+
61
+ Commands:
62
+
63
+ mpm -i <package> install from default repo
64
+ mpm -i -c <url> install from custom url
65
+ mpm -n <package> install from npm
66
+
67
+ Examples:
68
+
69
+ mpm -i math
70
+ mpm -i -c https://site.com/lib.ms
71
+ mpm -n lodash
72
+ `)
73
+ }
74
+
75
+ ensureDir(MODULES_DIR)
76
+
77
+ if (args.length == 0) {
78
+ usage()
79
+ process.exit(0)
80
+ }
81
+
82
+ try {
83
+ if (args[0] == "-i" || args[0] == "--install") {
84
+ if (args[1] == "-c" || args[1] == "--custom") {
85
+ const url = args[2]
86
+ if (!url) throw "Missing URL"
87
+ await installFromCustom(url)
88
+ } else {
89
+ const pkg = args[1]
90
+ if (!pkg) throw "Missing package name"
91
+ await installFromDefault(pkg)
92
+ }
93
+ }
94
+
95
+ else if (args[0] == "-n" || args[0] == "--npm") {
96
+ const pkg = args[1]
97
+ if (!pkg) throw "Missing npm package"
98
+ installFromNpm(pkg)
99
+ }
100
+
101
+ else {
102
+ usage()
103
+ }
104
+
105
+ console.log("Done.")
106
+ }
107
+ catch(e) {
108
+ console.error("\n[MPM ERROR]\n", e)
109
+ }
package/mpm/mpm.ms ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs"
3
+ import path from "path"
4
+ import https from "https"
5
+ import { execSync } from "child_process"
6
+
7
+ const args = process.argv.slice(2)
8
+ const CWD = process.cwd()
9
+ const MODULES_DIR = path.join(CWD, "ms_modules")
10
+ const DEFAULT_REPO = "https://ianlangs.github.io/mpm-ms/"
11
+
12
+ fn ensureDir(dir) {
13
+ if (!fs.existsSync(dir)) {
14
+ fs.mkdirSync(dir, { recursive: true })
15
+ }
16
+ }
17
+
18
+ fn download(url, dest) {
19
+ return new Promise((resolve, reject) => {
20
+ const file = fs.createWriteStream(dest)
21
+ https.get(url, res => {
22
+ if (res.statusCode !== 200) {
23
+ reject("HTTP " + res.statusCode)
24
+ return
25
+ }
26
+ res.pipe(file)
27
+ file.on("finish", () => {
28
+ file.close()
29
+ resolve()
30
+ })
31
+ }).on("error", err => {
32
+ fs.unlinkSync(dest)
33
+ reject(err)
34
+ })
35
+ })
36
+ }
37
+
38
+ fn installFromDefault(pkg) {
39
+ const url = DEFAULT_REPO + pkg + ".ms"
40
+ const dest = path.join(MODULES_DIR, pkg + ".ms")
41
+ console.log("Installing", pkg, "from", url)
42
+ return download(url, dest)
43
+ }
44
+
45
+ fn installFromCustom(url) {
46
+ const name = url.split("/").pop()
47
+ const dest = path.join(MODULES_DIR, name)
48
+ console.log("Installing", name, "from", url)
49
+ return download(url, dest)
50
+ }
51
+
52
+ fn installFromNpm(pkg) {
53
+ console.log("Installing from npm:", pkg)
54
+ execSync("npm install " + pkg, { stdio: "inherit" })
55
+ }
56
+
57
+ fn usage() {
58
+ console.log(`
59
+ mpm - MS Package Manager
60
+
61
+ Commands:
62
+
63
+ mpm -i <package> install from default repo
64
+ mpm -i -c <url> install from custom url
65
+ mpm -n <package> install from npm
66
+
67
+ Examples:
68
+
69
+ mpm -i math
70
+ mpm -i -c https://site.com/lib.ms
71
+ mpm -n lodash
72
+ `)
73
+ }
74
+
75
+ ensureDir(MODULES_DIR)
76
+
77
+ if (args.length == 0) {
78
+ usage()
79
+ process.exit(0)
80
+ }
81
+
82
+ try {
83
+ if (args[0] == "-i" || args[0] == "--install") {
84
+ if (args[1] == "-c" || args[1] == "--custom") {
85
+ const url = args[2]
86
+ if (!url) throw "Missing URL"
87
+ await installFromCustom(url)
88
+ } else {
89
+ const pkg = args[1]
90
+ if (!pkg) throw "Missing package name"
91
+ await installFromDefault(pkg)
92
+ }
93
+ }
94
+
95
+ else if (args[0] == "-n" || args[0] == "--npm") {
96
+ const pkg = args[1]
97
+ if (!pkg) throw "Missing npm package"
98
+ installFromNpm(pkg)
99
+ }
100
+
101
+ else {
102
+ usage()
103
+ }
104
+
105
+ console.log("Done.")
106
+ }
107
+ catch(e) {
108
+ console.error("\n[MPM ERROR]\n", e)
109
+ }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@ianlangs/mathscript",
4
- "version": "1.2.0",
4
+ "version": "1.6.0",
5
5
  "description": "superset de js",
6
- "main": "src/main.js",
6
+ "main": "src/transpile.js",
7
7
  "scripts": {
8
- "test": "node ./src/main.js --init"
8
+ "test": "node ./src/msc.js --init"
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",
@@ -24,8 +24,9 @@
24
24
  "url": "https://github.com/IanLangs/Mathscript/issues"
25
25
  },
26
26
  "bin": {
27
- "msc": "./src/main.js",
28
- "ms-node": "./src/node.js"
27
+ "msc": "./src/msc.js",
28
+ "ms-node": "./src/msnode.js",
29
+ "mpm": "./mpm/mpm.js"
29
30
  },
30
31
  "homepage": "https://github.com/IanLangs/Mathscript#readme"
31
32
  }
package/src/msc.js ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'fs'
3
+ import { transpile } from './transpile.js'
4
+
5
+ function init(files) {
6
+ const config = { Files: files }
7
+ fs.writeFileSync('msconfig.json', JSON.stringify(config, null, 4))
8
+ console.log('msconfig.json creado')
9
+ }
10
+
11
+ function transpileFiles(files) {
12
+ for (const file of files) {
13
+ const code = fs.readFileSync(file, 'utf-8')
14
+ const out = transpile(code, file)
15
+ fs.writeFileSync(file.replace(/\.ms$/, '.js'), out)
16
+ console.log(`✔ ${file}`)
17
+ }
18
+ }
19
+
20
+ function transpileFromConfig(path = 'msconfig.json') {
21
+ const config = JSON.parse(fs.readFileSync(path, 'utf-8'))
22
+ transpileFiles(config.Files)
23
+ }
24
+
25
+ const args = process.argv.slice(2)
26
+
27
+ if (args[0] === '--init' || args[0] === '-i') {
28
+ init(args.slice(1))
29
+ }
30
+ else if (args[0] === '--transpile' || args[0] === '-t') {
31
+ transpileFiles(args.slice(1))
32
+ }
33
+ else if (args.length === 0) {
34
+ transpileFromConfig()
35
+ }
36
+ else if (args.length === 1 && args[0].endsWith('.json')) {
37
+ transpileFromConfig(args[0])
38
+ }
39
+ else {
40
+ console.log(`Uso:
41
+
42
+ msc --init <archivos.ms>
43
+ msc -i <archivos.ms>
44
+
45
+ msc --transpile <archivos.ms>
46
+ msc -t <archivos.ms>
47
+
48
+ msc <config.json>
49
+ msc
50
+ `)
51
+ }
package/src/msnode.js ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'fs'
3
+ import { transpile } from './transpile.js'
4
+
5
+ const file = process.argv[2]
6
+
7
+ if (!file) {
8
+ console.log("Uso: ms-node archivo.ms")
9
+ process.exit(1)
10
+ }
11
+
12
+ const code = fs.readFileSync(file, 'utf-8')
13
+ const js = transpile(code, file)
14
+ eval(js)
package/src/transpile.js CHANGED
@@ -1,83 +1,93 @@
1
- const Consts = [
2
- [/::\s*[^\s\(\)]*/g, ""],
3
- [/mut\s+([a-zA-Z_]\w*)\s*=\s*(.+)/g, "let $1 = (()=>{let v=$2; return {get:()=>v,set:n=>v=n}})()"],
4
- [/immut\s+([a-zA-Z_]\w*)/g, "delete $1.set"],
5
- [/using\(/g, "require("],
6
- [/fn/g, "function"],
7
- ]
8
-
9
- function analyzeMS(code) {
10
- const lines = code.split("\n")
11
- const scopes = [new Map()] // nombre -> { mut: boolean, kind }
12
-
13
- function findVar(name) {
14
- for (let s of scopes) {
15
- if (s.has(name)) return s.get(name)
16
- }
17
- return null
18
- }
19
-
20
- lines.forEach((line, i) => {
21
- const ln = i + 1
22
- const trimmed = line.trim()
23
-
24
- if (trimmed.includes("{")) scopes.unshift(new Map())
25
- if (trimmed.includes("}")) scopes.shift()
26
-
27
- // mut x = ...
28
- const mutMatch = line.match(/^\s*mut\s+([a-zA-Z_]\w*)/)
29
- if (mutMatch) {
30
- const name = mutMatch[1]
31
- scopes[0].set(name, { mut: true, kind: "mut" })
32
- return
33
- }
1
+ export function transpile(code, filename = "<input>") {
2
+ code = code.replace("using(", "require(").replace(/::[^=\n\(\)]*/g, "").replace(/\bfn\b/g, "function")
3
+ const lines = code.split('\n')
4
+ const vars = new Map()
5
+ const output = []
34
6
 
35
- // let x = ...
36
- const letMatch = line.match(/^\s*let\s+([a-zA-Z_]\w*)/)
37
- if (letMatch) {
38
- const name = letMatch[1]
39
- scopes[0].set(name, { mut: false, kind: "let" })
40
- return
7
+ function error(line, msg) {
8
+ console.error(`\n[MS ERROR] ${filename}:${line}\n ${msg}\n`)
9
+ process.exit(1)
41
10
  }
42
11
 
43
- // const x = ...
44
- const constMatch = line.match(/^\s*const\s+([a-zA-Z_]\w*)/)
45
- if (constMatch) {
46
- const name = constMatch[1]
47
- scopes[0].set(name, { mut: false, kind: "const" })
48
- return
49
- }
12
+ for (let i = 0; i < lines.length; i++) {
13
+ const raw = lines[i]
14
+ const line = raw.trim()
15
+ const ln = i + 1
50
16
 
51
- // immut x
52
- const im = line.match(/^\s*immut\s+([a-zA-Z_]\w*)/)
53
- if (im) {
54
- const name = im[1]
55
- const v = findVar(name)
17
+ if (!line) {
18
+ output.push(raw)
19
+ continue
20
+ }
56
21
 
57
- if (!v) {
58
- throw new Error(`MS Compile Error (line ${ln}): '${name}' is not declared`)
59
- }
22
+ // mut x = value
23
+ let m = line.match(/^mut\s+([a-zA-Z_]\w*)\s*=\s*(.+)$/)
24
+ if (m) {
25
+ const name = m[1]
26
+ const value = m[2]
60
27
 
61
- if (!v.mut) {
62
- throw new Error(
63
- `MS Compile Error (line ${ln}): '${name}' is not mutable (declared as ${v.kind})`
64
- )
65
- }
28
+ if (vars.has(name)) {
29
+ error(ln, `'${name}' ya está declarada`)
30
+ }
66
31
 
67
- v.mut = false
68
- return
69
- }
70
- })
71
- }
32
+ vars.set(name, { mutable: true })
33
+ output.push(`let ${name} = ${value}`)
34
+ continue
35
+ }
36
+
37
+ // immut x
38
+ m = line.match(/^immut\s+([a-zA-Z_]\w*)$/)
39
+ if (m) {
40
+ const name = m[1]
41
+
42
+ if (!vars.has(name)) {
43
+ error(ln, `'${name}' no está declarada`)
44
+ }
72
45
 
46
+ const info = vars.get(name)
47
+ if (!info.mutable) {
48
+ error(ln, `'${name}' no es mutable`)
49
+ }
73
50
 
74
- function transpile(code, ...consts) {
75
- analyzeMS(code)
51
+ info.mutable = false
52
+ continue
53
+ }
54
+
55
+ // x = y
56
+ m = line.match(/^([a-zA-Z_]\w*)\s*=\s*(.+)$/)
57
+ if (m) {
58
+ const name = m[1]
59
+
60
+ if (vars.has(name)) {
61
+ const info = vars.get(name)
62
+ if (!info.mutable) {
63
+ error(ln, `'${name}' es inmutable`)
64
+ }
65
+ }
66
+
67
+ output.push(raw)
68
+ continue
69
+ }
70
+
71
+ // let x =
72
+ m = line.match(/^let\s+([a-zA-Z_]\w*)\s*=/)
73
+ if (m) {
74
+ vars.set(m[1], { mutable: true })
75
+ output.push(raw)
76
+ continue
77
+ }
78
+
79
+ // const x =
80
+ m = line.match(/^const\s+([a-zA-Z_]\w*)\s*=/)
81
+ if (m) {
82
+ vars.set(m[1], { mutable: false })
83
+ output.push(raw)
84
+ continue
85
+ }
86
+
87
+ output.push(raw)
88
+ }
76
89
 
77
- for (let [i, j] of consts) {
78
- code = code.replace(i, j)
79
- }
80
- return code
90
+ return output.join('\n')
81
91
  }
82
92
 
83
- export default { transpile, Consts }
93
+ export default { transpile }
package/src/web-t.js ADDED
File without changes
package/tests/funcs.js CHANGED
@@ -4,7 +4,7 @@ function suma(a, b) {
4
4
 
5
5
  console.log(suma(3, 4)) // 7
6
6
 
7
- function saludo(nombre) {
7
+ function saludo(nombre ) {
8
8
  return "Hola " + nombre
9
9
  }
10
10
 
package/tests/vars.js CHANGED
@@ -1,13 +1,12 @@
1
1
  // Mutable
2
- let x = (()=>{let v=5; return {get:()=>v,set:n=>v=n}})()
3
- console.log(x.get()) // 5
4
- x.set(10)
5
- console.log(x.get()) // 10
2
+ let x = 5
3
+ console.log(x) // 5
4
+ x = 10
5
+ console.log(x) // 10
6
6
 
7
7
  // Inmutable
8
- delete x.set
9
8
  try {
10
- x.set(20) // debería dar error
9
+ //x = 20 // debería dar error
11
10
  } catch(e) {
12
11
  console.log("error mutabilidad") // esperado
13
12
  }
@@ -15,7 +14,7 @@ try {
15
14
  // Variable
16
15
  let y = "hola"
17
16
  console.log(y) // "hola"
18
- // delete y.set // error no es mutable
17
+ // immut y // error no es mutable
19
18
 
20
19
 
21
20
  // Const
package/tests/vars.ms CHANGED
@@ -1,16 +1,12 @@
1
1
  // Mutable
2
- mut x::number = 5
3
- console.log(x.get()) // 5
4
- x.set(10)
5
- console.log(x.get()) // 10
2
+ mut x = 5
3
+ console.log(x) // 5
4
+ x = 10
5
+ console.log(x) // 10
6
6
 
7
7
  // Inmutable
8
8
  immut x
9
- try {
10
- x.set(20) // debería dar error
11
- } catch(e) {
12
- console.log("error mutabilidad") // esperado
13
- }
9
+ //x = 20 // error
14
10
 
15
11
  // Variable
16
12
  let y = "hola"
package/src/main.js DELETED
@@ -1,29 +0,0 @@
1
- #!/bin/env node
2
- import T from './transpile.js'
3
- import fs from 'fs'
4
-
5
- function processConfig(config) {
6
- for (let file of config.Files) {
7
- try {
8
- let code = fs.readFileSync(file, "utf-8")
9
- code = T.transpile(code, ...(T.Consts))
10
- fs.writeFileSync(file.replace(/\.ms$/g, ".js"), code, 'utf-8')
11
- } catch(e) {
12
- console.error(`Error procesando ${file}:`, e.message)
13
- }
14
- }
15
- }
16
-
17
- if(process.argv[2] == "-i" || process.argv[2] == "--init") {
18
- let config = {Files:[]}
19
- config.Files = process.argv.slice(3)
20
- fs.writeFileSync("msconfig.json", JSON.stringify(config, ["Files"], 4))
21
- process.exit(0)
22
- } else if (process.argv[2] == "-t" || process.argv[2] == "--transpile") {
23
- let config = {Files:process.argv.slice(3)}
24
- processConfig(config)
25
- } else if (process.argv.length == 2) {
26
- processConfig(JSON.parse(fs.readFileSync("msconfig.json", 'utf-8')))
27
- } else if (process.argv.length == 3) {
28
- processConfig(JSON.parse(fs.readFileSync(process.argv[2], 'utf-8')))
29
- }
package/src/node.js DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env node
2
- import fs from "fs"
3
- import T from "./transpile.js"
4
-
5
- const file = process.argv[2]
6
- if (!file) {
7
- console.error("Usage: ms-node <file.ms>")
8
- process.exit(1)
9
- }
10
-
11
-
12
- const source = fs.readFileSync(file, "utf-8")
13
- const js = T.transpile(source, ...(T.Consts))
14
- const run = new Function(js)
15
- run()