Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update JS to newest standard #307

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
49149df
XOR and updated not equal syntax
Ashvin-Ranjan Aug 28, 2022
9a599c8
bitwise operators and updated enum syntax
Ashvin-Ranjan Aug 28, 2022
c69cb9f
update record syntax
Ashvin-Ranjan Aug 28, 2022
09ad09d
Update some of the internal libraries
Ashvin-Ranjan Aug 28, 2022
6adadd2
update | operator
Ashvin-Ranjan Aug 28, 2022
ee49b64
~ for maybe types
Ashvin-Ranjan Aug 28, 2022
59ab81d
update FileIO and function syntax
Ashvin-Ranjan Aug 29, 2022
d039d83
indexing
Ashvin-Ranjan Aug 30, 2022
8e1ff4a
update var statement
Ashvin-Ranjan Aug 31, 2022
c77baf5
a bit of work on traits
Ashvin-Ranjan Sep 2, 2022
75f54ae
some spreading work
Ashvin-Ranjan Sep 4, 2022
03d63fc
fix merge issues
Ashvin-Ranjan Sep 4, 2022
2170ad1
some very sketchy internal traits code
Ashvin-Ranjan Sep 4, 2022
ef3a7af
fix many, many things
Ashvin-Ranjan Sep 4, 2022
b7b6430
remove old for loop
Ashvin-Ranjan Sep 4, 2022
3449c6f
fix many issues
Ashvin-Ranjan Sep 5, 2022
a43e9b6
format every file
Ashvin-Ranjan Sep 5, 2022
073087f
I have no clue what is wrong with the website please help
Ashvin-Ranjan Sep 13, 2022
0fcd148
working but scuffed editor, will deploy
Ashvin-Ranjan Sep 14, 2022
e7c3dd9
Some small fixes
Ashvin-Ranjan Sep 14, 2022
59d9f3c
Some small changes
Ashvin-Ranjan Sep 14, 2022
3c7ff8a
Fix bad error
Ashvin-Ranjan Sep 14, 2022
eafd287
fix spread and add while
Ashvin-Ranjan Sep 15, 2022
0be179a
enums are working better but are still slightly broken
Ashvin-Ranjan Nov 14, 2022
30a1a1b
Merge branch 'sean' of https://github.com/nbuilding/N-lang into sean
Ashvin-Ranjan Aug 23, 2024
8290789
I do not understand why subsection is not working
Ashvin-Ranjan Aug 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,6 @@ dmypy.json

# Ignored
ignored

# Examples
examples/
1 change: 1 addition & 0 deletions js/.prettierrc.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
trailingComma: all
arrowParens: avoid
singleQuote: true
4 changes: 2 additions & 2 deletions js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "n-lang",
"version": "1.3.2",
"version": "0.1.0",
"description": "A programming language for N Building.",
"main": "src/index.js",
"scripts": {
Expand Down
4 changes: 3 additions & 1 deletion js/scripts/js-to-lines.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ async function jsFileToLines (path, requirableNames = []) {
: JSON.stringify(line)
})
.join(',')
ts += `${exportName}: (name${
// __ is replaced with . for internal traits
const needsQuotes = exportName.indexOf('__') !== -1
ts += `${needsQuotes ? "'" : ''}${exportName.replace('__', '.')}${needsQuotes ? "'" : ''}: (name${
requiresRequire ? ', require' : ''
}) => [${lines}],\n\n`
}
Expand Down
139 changes: 70 additions & 69 deletions js/src/ast/base.ts
Original file line number Diff line number Diff line change
@@ -1,123 +1,124 @@
import colours from 'colors/safe'
import util from 'util'
import colours from 'colors/safe';
import util from 'util';

import { displayType } from '../utils/display-type'
import { displayType } from '../utils/display-type';

export interface BasePosition {
line: number
col: number
endLine: number
endCol: number
line: number;
col: number;
endLine: number;
endCol: number;
}
function posHas (
function posHas(
{ line: startLine, col: startCol, endLine, endCol }: BasePosition,
line: number,
col: number,
): boolean {
if (line > startLine && line < endLine) {
return true
return true;
} else if (line === startLine) {
if (col < startCol) return false
return line === endLine ? col <= endCol : true
if (col < startCol) return false;
return line === endLine ? col <= endCol : true;
} else if (line === endLine) {
return col <= endCol
return col <= endCol;
} else {
return false
return false;
}
}

export class Base {
line: number
col: number
endLine: number
endCol: number
line: number;
col: number;
endLine: number;
endCol: number;

/**
* Should contain every Base kept by the class.
*/
children: Base[]
children: Base[];

constructor (
constructor(
{ line, col, endLine, endCol }: BasePosition,
children: (Base | null)[] = [],
) {
this.line = line
this.col = col
this.endLine = endLine
this.endCol = endCol
this.children = children.filter((item): item is Base => item !== null)
this.line = line;
this.col = col;
this.endLine = endLine;
this.endCol = endCol;
this.children = children.filter((item): item is Base => item !== null);
}

find (line: number, col: number): Base[] {
find(line: number, col: number): Base[] {
if (posHas(this, line, col)) {
const bases: Base[] = []
const bases: Base[] = [];
for (const base of this.children) {
if (posHas(base, line, col)) {
bases.push(...base.find(line, col))
bases.push(...base.find(line, col));
}
}
bases.push(this)
return bases
bases.push(this);
return bases;
} else {
return []
return [];
}
}

diff (other: this, path = '.'): BaseDiff[] {
diff(other: this, path = '.'): BaseDiff[] {
if (this.constructor !== other.constructor) {
return [{ path, this: this.toString(), other: other.toString() }]
return [{ path, this: this.toString(), other: other.toString() }];
}
const issues = []
const issues = [];
for (const key in this) {
if (ignoredDiffKeys.includes(key)) continue
const propPath = `${path}/${this.constructor.name}.${key}`
const value = this[key]
const otherValue = other[key]
issues.push(...diffValues(propPath, value, otherValue))
if (ignoredDiffKeys.includes(key)) continue;
const propPath = `${path}/${this.constructor.name}.${key}`;
const value = this[key];
const otherValue = other[key];
issues.push(...diffValues(propPath, value, otherValue));
}
return issues
return issues;
}

toString (): string {
return `[undisplayable ${this.constructor.name}]`
toString(): string {
return `[undisplayable ${this.constructor.name}]`;
}

// Make the output of util.inspect cleaner
[util.inspect.custom] (): unknown {
const obj = { ...(this as Record<string, unknown>) }
// Is ? because if it is not in the node env it will cause errors
[util?.inspect?.custom]?(): unknown {
const obj = { ...(this as Record<string, unknown>) };
// Sets a hidden value
Object.defineProperty(obj, 'constructor', {
value: this.constructor,
})
delete obj.line
delete obj.col
delete obj.endLine
delete obj.endCol
delete obj.children
return obj
});
delete obj.line;
delete obj.col;
delete obj.endLine;
delete obj.endCol;
delete obj.children;
return obj;
}
}

export interface BaseDiff {
path: string
this: string
other: string
path: string;
this: string;
other: string;
}

const ignoredDiffKeys = ['line', 'col', 'endLine', 'endCol', 'children']
const ignoredDiffKeys = ['line', 'col', 'endLine', 'endCol', 'children'];

function diffValues (path: string, one: unknown, other: unknown): BaseDiff[] {
const issues = []
function diffValues(path: string, one: unknown, other: unknown): BaseDiff[] {
const issues = [];
if (typeof one === 'string' && typeof other === 'string') {
if (one !== other) {
return [{ path, this: one, other }]
return [{ path, this: one, other }];
}
} else if (
(typeof one === 'boolean' && typeof other === 'boolean') ||
(typeof one === 'number' && typeof other === 'number')
) {
if (one !== other) {
return [{ path, this: one.toString(), other: other.toString() }]
return [{ path, this: one.toString(), other: other.toString() }];
}
} else if (Array.isArray(one) && Array.isArray(other)) {
if (one.length !== other.length) {
Expand All @@ -127,36 +128,36 @@ function diffValues (path: string, one: unknown, other: unknown): BaseDiff[] {
this: `${one.length} item(s):\n${one.join('\n')}`,
other: `${other.length} item(s):\n${other.join('\n')}`,
},
]
];
}
for (let i = 0; i < one.length; i++) {
issues.push(...diffValues(`${path}[${i}]`, one[i], other[i]))
issues.push(...diffValues(`${path}[${i}]`, one[i], other[i]));
}
} else if (one instanceof Base && other instanceof Base) {
return one.diff(other)
return one.diff(other);
} else if (typeof one === 'function' && typeof other === 'function') {
return []
return [];
} else {
throw new TypeError(
`I do not know how to diff these types: ${displayType(
one,
)} vs ${displayType(other)}`,
)
);
}
return issues
return issues;
}

export class DiffError extends Error {
constructor (diffs: BaseDiff[]) {
super(diffs.map(DiffError.display).join('\n\n'))
this.name = this.constructor.name
constructor(diffs: BaseDiff[]) {
super(diffs.map(DiffError.display).join('\n\n'));
this.name = this.constructor.name;
}

static display (diff: BaseDiff): string {
static display(diff: BaseDiff): string {
return [
colours.bold(colours.white(diff.path)),
colours.cyan(diff.this),
colours.magenta(diff.other),
].join('\n')
].join('\n');
}
}
59 changes: 29 additions & 30 deletions js/src/ast/condition/Condition.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,59 @@
import { CompilationScope } from '../../compiler/CompilationScope'
import { ErrorType } from '../../type-checker/errors/Error'
import { Scope } from '../../type-checker/Scope'
import { ScopeBaseContext } from '../../type-checker/ScopeBaseContext'
import { bool } from '../../type-checker/types/builtins'
import { CompilationScope } from '../../compiler/CompilationScope';
import { ErrorType } from '../../type-checker/errors/Error';
import { Scope } from '../../type-checker/Scope';
import { ScopeBaseContext } from '../../type-checker/ScopeBaseContext';
import { bool } from '../../type-checker/types/builtins';
import {
CompilationResult,
Expression,
isExpression,
} from '../expressions/Expression'
import { Return } from '../expressions/Return'
import { IfLet } from './IfLet'
} from '../expressions/Expression';
import { Return } from '../expressions/Return';
import { IfLet } from './IfLet';

export type Condition = Expression | IfLet
export type Condition = Expression | IfLet;

export function isCondition (value: unknown): value is Condition {
return value instanceof IfLet || isExpression(value)
export function isCondition(value: unknown): value is Condition {
return value instanceof IfLet || isExpression(value);
}

export interface ConditionResult {
scope: Scope
exitPoint?: Return
scope: Scope;
exitPoint?: Return;
}

export function checkCondition (
export function checkCondition(
context: ScopeBaseContext,
condition: Condition,
): ConditionResult {
if (condition instanceof IfLet) {
return condition.checkIfLet(context)
return condition.checkIfLet(context);
} else {
const { type, exitPoint } = context.scope.typeCheck(condition)
context.isTypeError(ErrorType.CONDITION_NOT_BOOL, bool, type)
return { scope: context.scope.inner(), exitPoint }
const { type, exitPoint } = context.scope.typeCheck(condition);
context.isTypeError(ErrorType.CONDITION_NOT_BOOL, bool, type);
return { scope: context.scope.inner(), exitPoint };
}
}

export type ConditionCompilationResult = {
statements: string[]
result: string
}
statements: string[];
result: string;
};

/**
* `scope` is the scope specifically for the "then" branch of the if
* statement/expression. Unlike `checkCondition`, this function won't create an
* inner scope for you.
*/
export function compileCondition (
export function compileCondition(
scope: CompilationScope,
condition: Condition,
): ConditionCompilationResult {
if (condition instanceof IfLet) {
const { statements: exprS, expression } = condition.expression.compile(
scope,
)
const expressionName = scope.context.genVarName('ifLetValue')
const resultName = scope.context.genVarName('ifLetResult')
const { statements: exprS, expression } =
condition.expression.compile(scope);
const expressionName = scope.context.genVarName('ifLetValue');
const resultName = scope.context.genVarName('ifLetResult');
return {
statements: [
...exprS,
Expand All @@ -66,12 +65,12 @@ export function compileCondition (
),
],
result: resultName,
}
};
} else {
const { statements, expression } = condition.compile(scope)
const { statements, expression } = condition.compile(scope);
return {
statements,
result: expression,
}
};
}
}
Loading