@ianlangs/mathscript 1.2.0 → 1.4.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/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.4.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,8 @@
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
29
  },
30
30
  "homepage": "https://github.com/IanLangs/Mathscript#readme"
31
31
  }
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/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()