Skip to content

Commit 9512610

Browse files
committed
initial commit
0 parents  commit 9512610

17 files changed

+752
-0
lines changed

.eslintrc.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es2021": true
5+
},
6+
"parser": "@typescript-eslint/parser",
7+
"parserOptions": {
8+
"ecmaVersion": "latest",
9+
"sourceType": "module"
10+
},
11+
"plugins": [
12+
"@typescript-eslint"
13+
],
14+
"rules": {
15+
"quotes":["warn","single"],
16+
"semi":"error",
17+
"comma-dangle":"error"
18+
}
19+
}

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/.git
2+
/dist
3+
/syx
4+
/node_modules
5+
6+
package-lock.json
7+
syxconfig.json

.vscode/tasks.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"type": "typescript",
6+
"tsconfig": "tsconfig.json",
7+
"option": "watch",
8+
"problemMatcher": [
9+
"$tsc-watch"
10+
],
11+
"group": "build",
12+
"label": "tsc: izleme - tsconfig.json"
13+
}
14+
]
15+
}

package.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "syntaxs",
3+
"version": "0.0.1-alpha",
4+
"description": "Syntax Script Command Line Interface.",
5+
"main": "./dist/index.js",
6+
"scripts": {
7+
"build": "eslint ./src/**/*.ts --fix && eslint ./src/**/*.ts && tsc && cls"
8+
},
9+
"keywords": [
10+
"syntax",
11+
"ss",
12+
"script"
13+
],
14+
"author": "efekos",
15+
"license": "MIT",
16+
"devDependencies": {
17+
"@types/chalk": "^2.2.0",
18+
"@types/figlet": "^1.5.8",
19+
"@types/inquirer": "^9.0.7",
20+
"@types/node": "^20.11.30",
21+
"@typescript-eslint/eslint-plugin": "^7.4.0",
22+
"@typescript-eslint/parser": "^7.4.0",
23+
"eslint": "^8.57.0"
24+
},
25+
"dependencies": {
26+
"chalk": "^5.3.0",
27+
"figlet": "^1.7.0",
28+
"inquirer": "9.2.16",
29+
"nanospinner": "1.1.0"
30+
},
31+
"type": "module",
32+
"bin": {
33+
"syntaxs": "./dist/index.js"
34+
}
35+
}

src/argument/ArgResolver.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import chalk from 'chalk';
2+
import { log } from '../log.js';
3+
4+
export namespace arg {
5+
6+
export const full: string[] = process.argv.slice(2);
7+
8+
const args: Record<string, string> = {};
9+
const flags: string[] = [];
10+
let command: string = undefined;
11+
12+
const argumentRegex = /^-([a-z]+)$/;
13+
const flagRegex = /^--([a-z]+)$/;
14+
15+
export function resolve() {
16+
17+
for (let i = 0; i < full.length; i++) {
18+
const s = full[i];
19+
20+
if (!s.startsWith('-') && command === undefined) command = s;
21+
22+
if (s.match(argumentRegex)) {
23+
if (full[i + 1] === undefined || full[i + 1].match(argumentRegex) || full[i + 1].match(flagRegex)) log.exit.error(`Argument ${chalk.gray(s)} not specified`);
24+
args[s.slice(1)] = full[i + 1];
25+
i++;
26+
}
27+
28+
if (s.match(flagRegex)) flags.push(s.slice(2));
29+
}
30+
31+
}
32+
33+
export function getCommand() {
34+
return command ?? '';
35+
}
36+
37+
export function hasFlag(flag: string): boolean {
38+
return flags.includes(flag);
39+
}
40+
41+
export function getArgument(arg: string,required:boolean = false): string | undefined {
42+
if(args[arg]===undefined&&required) log.exit.error(`Argument ${chalk.gray(arg)} required`);
43+
return args[arg];
44+
}
45+
46+
}

src/command/help.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import figlet from 'figlet';
2+
import { log } from '../log.js';
3+
import chalk from 'chalk';
4+
5+
export async function runHelp() {
6+
await console.clear();
7+
await figlet('syntaxs | 0.0.1-alpha', (e, r) => { log.raw(r); });
8+
9+
10+
log.raw('');
11+
log.info(
12+
'----------------------------------------------------------------------',
13+
'Commands:',
14+
'',
15+
' help Print this',
16+
` version,${chalk.gray('--version')},${chalk.gray('--v')} Print version`,
17+
' logs Test all log types',
18+
` tokenize ${chalk.gray('-input')} <path> ${chalk.gray('-write')} [path] Tokenize source file`,
19+
` parse ${chalk.gray('-input')} <path> ${chalk.gray('-write')} [path] Parse source file`
20+
);
21+
}

src/command/init.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { existsSync, mkdirSync, writeFileSync } from 'fs';
2+
import { join } from 'path';
3+
import { log } from '../log.js';
4+
import inquirer from 'inquirer';
5+
import { arg } from '../argument/ArgResolver.js';
6+
import chalk from 'chalk';
7+
import { errorChecks } from '../utils.js';
8+
9+
export interface InitContext {
10+
name:string;
11+
description:string;
12+
version:string;
13+
input:string;
14+
output:string;
15+
}
16+
17+
export async function runInit(){
18+
if(existsSync(join(process.cwd(),'syxconfig.json'))) log.exit.error('There is already a \'syxconfig.json\' file, delete it.');
19+
20+
if(arg.hasFlag('y')) errorChecks([
21+
[existsSync(join(process.cwd(),'src')),`Folder already exists: src. Define another folder by running without ${chalk.gray('--y')}.`],
22+
[existsSync(join(process.cwd(),'out')),`Folder already exists: out. Define another folder by running without ${chalk.gray('--y')}.`]
23+
]);
24+
25+
const context:InitContext = !arg.hasFlag('y') ? await inquirer.prompt([
26+
{
27+
type:'input',
28+
message:'Name',
29+
default:process.cwd().split('\\').pop(),
30+
name:'name'
31+
},
32+
{
33+
type:'input',
34+
message:'Description',
35+
name:'description'
36+
},
37+
{
38+
type:'input',
39+
message:'Version',
40+
default:'1.0.0',
41+
name:'version'
42+
},
43+
{
44+
type:'input',
45+
message:'Root directory',
46+
default:'./src',
47+
name:'input'
48+
},
49+
{
50+
type:'input',
51+
message:'Out directory',
52+
default:'./out',
53+
name:'output'
54+
}
55+
]) : {name:process.cwd().split('\\').pop(),description:'',version:'',input:'./src',output:'./out'};
56+
57+
const file = {name:context.name,description:context.description,version:context.version,compiler:{root:context.input,out:context.output}};
58+
59+
errorChecks([
60+
[existsSync(join(process.cwd(),context.input)),`Root directory '${context.input}' already exists. Delete it or define another directory.`],
61+
[existsSync(join(process.cwd(),context.output)),`Out directory '${context.output}' already exists. Delete it or define another directory.`]
62+
]);
63+
64+
const fileToWrite = JSON.stringify(file,undefined,4);
65+
66+
log.raw('',fileToWrite,'');
67+
const r:{r:boolean} = await inquirer.prompt({
68+
message:'Are you okay with this output?',
69+
type:'confirm',
70+
name:'r'
71+
});
72+
73+
if(r.r){
74+
writeFileSync(join(process.cwd(),'syxconfig.json'),fileToWrite,{encoding:'utf8'});
75+
76+
await mkdirSync(join(process.cwd(),context.input), {recursive:true});
77+
log.success('Created root folder.');
78+
await mkdirSync(join(process.cwd(),context.output),{recursive:true});
79+
log.success('Created out folder.');
80+
81+
log.success('Created \'syxconfig.json\' file.');
82+
}
83+
84+
}

src/command/logs.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { log } from '../log.js';
2+
3+
export async function runLogs(){
4+
log.error('Error message');
5+
log.success('Success message');
6+
log.info('Info message');
7+
log.notice('Notice message');
8+
log.warn('Warn message');
9+
}

src/command/parse.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import chalk from 'chalk';
2+
import { arg } from '../argument/ArgResolver.js';
3+
import { errorChecks } from '../utils.js';
4+
import { join } from 'path';
5+
import { existsSync, readFileSync, writeFileSync } from 'fs';
6+
import { tokenize } from '../compiler/lexer.js';
7+
import { log } from '../log.js';
8+
import { parser } from '../compiler/ast.js';
9+
10+
export async function runParse() {
11+
12+
const input = arg.getArgument('input')??arg.getArgument('i');
13+
const write = arg.getArgument('write')??'';
14+
15+
errorChecks([
16+
[input===undefined,`Missing argument ${chalk.gray('-input')} or ${chalk.gray('-i')}`]
17+
]);
18+
19+
const inputPath = join(process.cwd(),input);
20+
21+
errorChecks([
22+
[!existsSync(inputPath),`File not found: ${inputPath}`]
23+
]);
24+
25+
26+
const parsed = parser.parseTokens(tokenize(readFileSync(inputPath).toString()));
27+
if(write==='')log.info('',...JSON.stringify(parsed,undefined,4).split('\n'),'');
28+
log.info(`Created ${parsed.body.length} statements from source file '${inputPath}'`);
29+
if(write!==''){
30+
31+
writeFileSync(join(process.cwd(),write),JSON.stringify(parsed,undefined,4));
32+
log.info(`Wrote the output into the file ${join(process.cwd(),write)}`);
33+
}
34+
}

src/command/tokenize.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import chalk from 'chalk';
2+
import { arg } from '../argument/ArgResolver.js';
3+
import { errorChecks } from '../utils.js';
4+
import { join } from 'path';
5+
import { existsSync, readFileSync, writeFileSync } from 'fs';
6+
import { tokenize } from '../compiler/lexer.js';
7+
import { log } from '../log.js';
8+
9+
export async function runTokenize() {
10+
11+
const input = arg.getArgument('input')??arg.getArgument('i');
12+
const write = arg.getArgument('write')??'';
13+
14+
errorChecks([
15+
[input===undefined,`Missing argument ${chalk.gray('-input')} or ${chalk.gray('-i')}`]
16+
]);
17+
18+
const inputPath = join(process.cwd(),input);
19+
20+
errorChecks([
21+
[!existsSync(inputPath),`File not found: ${inputPath}`]
22+
]);
23+
24+
25+
const tokens = tokenize(readFileSync(inputPath).toString());
26+
if(write==='')log.info('',...JSON.stringify(tokens,undefined,4).split('\n'),'');
27+
log.info(`Created ${tokens.length} tokens from source file '${inputPath}'`);
28+
if(write!==''){
29+
30+
writeFileSync(join(process.cwd(),write),JSON.stringify(tokens,undefined,4));
31+
log.info(`Wrote the output into the file ${join(process.cwd(),write)}`);
32+
}
33+
}

0 commit comments

Comments
 (0)