mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
add eslint
This commit is contained in:
parent
e951cd5ee1
commit
12fcc4f1bb
11 changed files with 1237 additions and 26 deletions
27
.eslintrc.cjs
Normal file
27
.eslintrc.cjs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* eslint-env node */
|
||||||
|
module.exports = {
|
||||||
|
ignorePatterns: ["/target/**", "/jest.config.js"],
|
||||||
|
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||||
|
parser: "@typescript-eslint/parser",
|
||||||
|
plugins: ["@typescript-eslint"],
|
||||||
|
root: true,
|
||||||
|
rules: {
|
||||||
|
// Sometimes you just need a `while(true)`.
|
||||||
|
"no-constant-condition": "off",
|
||||||
|
// Typescript already checks problematic fallthrough.
|
||||||
|
// The eslint rule is a bit dumb and also complains about
|
||||||
|
// obvious clear fallthrough like `case "a": case "b"`.
|
||||||
|
"no-fallthrough": "off",
|
||||||
|
// Suppress no-unused-vars with leading underscores.
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
varsIgnorePattern: "^_",
|
||||||
|
argsIgnorePattern: "^_",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// `any` is genrally bad, but sometimes it's the nicest solution
|
||||||
|
// Just let me use it without any ceremony.
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
},
|
||||||
|
};
|
||||||
1
eslintignore
Normal file
1
eslintignore
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
1181
package-lock.json
generated
1181
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,6 +13,9 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.3",
|
"@types/jest": "^29.5.3",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
||||||
|
"@typescript-eslint/parser": "^6.2.0",
|
||||||
|
"eslint": "^8.46.0",
|
||||||
"jest": "^29.6.1",
|
"jest": "^29.6.1",
|
||||||
"node-dev": "^8.0.0",
|
"node-dev": "^8.0.0",
|
||||||
"prettier": "^2.0.0",
|
"prettier": "^2.0.0",
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ export function tokenize(input: string): Token[] {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
const ident = input.slice(span.start, span.end);
|
const ident = input.slice(span.start, span.end);
|
||||||
let kw = isKeyword(ident);
|
const kw = isKeyword(ident);
|
||||||
if (kw) {
|
if (kw) {
|
||||||
tokens.push({ kind: kw, span });
|
tokens.push({ kind: kw, span });
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -331,7 +331,7 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
||||||
}
|
}
|
||||||
case "literal": {
|
case "literal": {
|
||||||
switch (expr.value.kind) {
|
switch (expr.value.kind) {
|
||||||
case "str":
|
case "str": {
|
||||||
const utf8 = encodeUtf8(expr.value.value);
|
const utf8 = encodeUtf8(expr.value.value);
|
||||||
const idx = appendData(fcx.cx, utf8);
|
const idx = appendData(fcx.cx, utf8);
|
||||||
|
|
||||||
|
|
@ -339,6 +339,7 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
||||||
instrs.push({ kind: "i32.const", imm: utf8.length });
|
instrs.push({ kind: "i32.const", imm: utf8.length });
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "int":
|
case "int":
|
||||||
switch (expr.value.type) {
|
switch (expr.value.type) {
|
||||||
case "Int":
|
case "Int":
|
||||||
|
|
@ -573,11 +574,9 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
||||||
|
|
||||||
// TODO: Actually do this instead of being naive.
|
// TODO: Actually do this instead of being naive.
|
||||||
|
|
||||||
const isPlace = (expr: Expr) =>
|
const _isPlace = (expr: Expr) =>
|
||||||
expr.kind === "ident" || expr.kind === "fieldAccess";
|
expr.kind === "ident" || expr.kind === "fieldAccess";
|
||||||
|
|
||||||
function project() {}
|
|
||||||
|
|
||||||
lowerExpr(fcx, instrs, expr.lhs);
|
lowerExpr(fcx, instrs, expr.lhs);
|
||||||
|
|
||||||
switch (expr.lhs.ty!.kind) {
|
switch (expr.lhs.ty!.kind) {
|
||||||
|
|
|
||||||
|
|
@ -344,6 +344,7 @@ function parseExprCall(t: Token[]): [Token[], Expr] {
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseExprAtom(startT: Token[]): [Token[], Expr] {
|
function parseExprAtom(startT: Token[]): [Token[], Expr] {
|
||||||
|
// eslint-disable-next-line prefer-const
|
||||||
let [t, tok] = next(startT);
|
let [t, tok] = next(startT);
|
||||||
const span = tok.span;
|
const span = tok.span;
|
||||||
|
|
||||||
|
|
@ -354,8 +355,7 @@ function parseExprAtom(startT: Token[]): [Token[], Expr] {
|
||||||
// This could be a block or a tuple literal. We can only know after
|
// This could be a block or a tuple literal. We can only know after
|
||||||
// parsing the first expression and looking at the delimiter.
|
// parsing the first expression and looking at the delimiter.
|
||||||
|
|
||||||
let peek;
|
const [, peek] = next(t);
|
||||||
[, peek] = next(t);
|
|
||||||
// It's a single element, which we interpret as a block.
|
// It's a single element, which we interpret as a block.
|
||||||
// `(0,)` is the one elem tuple.
|
// `(0,)` is the one elem tuple.
|
||||||
if (peek.kind === ")") {
|
if (peek.kind === ")") {
|
||||||
|
|
@ -579,11 +579,7 @@ function parseCommaSeparatedList<R>(
|
||||||
|
|
||||||
// () | (a) | (a,) | (a, b)
|
// () | (a) | (a,) | (a, b)
|
||||||
|
|
||||||
while (true) {
|
while (next(t)[1]?.kind !== terminator) {
|
||||||
if (next(t)[1]?.kind === terminator) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let nextValue;
|
let nextValue;
|
||||||
[t, nextValue] = parser(t);
|
[t, nextValue] = parser(t);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,8 +191,8 @@ function resolveModule(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case "let": {
|
case "let": {
|
||||||
let rhs = this.expr(expr.rhs);
|
const rhs = this.expr(expr.rhs);
|
||||||
let type = expr.type && this.type(expr.type);
|
const type = expr.type && this.type(expr.type);
|
||||||
|
|
||||||
scopes.push(expr.name.name);
|
scopes.push(expr.name.name);
|
||||||
const local = { name: expr.name.name, span: expr.name.span };
|
const local = { name: expr.name.name, span: expr.name.span };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { TY_INT, TY_STRING, TY_UNIT, Ty } from "./ast";
|
import { TY_INT, TY_STRING, TY_UNIT } from "./ast";
|
||||||
import { DUMMY_SPAN as SPAN } from "./error";
|
import { DUMMY_SPAN as SPAN } from "./error";
|
||||||
import { InferContext } from "./typeck";
|
import { InferContext } from "./typeck";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import {
|
import {
|
||||||
Ast,
|
Ast,
|
||||||
binaryExprPrecedenceClass,
|
|
||||||
BuiltinName,
|
BuiltinName,
|
||||||
COMPARISON_KINDS,
|
COMPARISON_KINDS,
|
||||||
DEFAULT_FOLDER,
|
DEFAULT_FOLDER,
|
||||||
|
|
@ -298,7 +297,7 @@ export function typeck(ast: Ast): Ast {
|
||||||
}
|
}
|
||||||
case "mod": {
|
case "mod": {
|
||||||
switch (item.node.modKind.kind) {
|
switch (item.node.modKind.kind) {
|
||||||
case "inline":
|
case "inline": {
|
||||||
const modKind: ModItemKind = {
|
const modKind: ModItemKind = {
|
||||||
kind: "inline",
|
kind: "inline",
|
||||||
contents: item.node.modKind.contents.map((item) =>
|
contents: item.node.modKind.contents.map((item) =>
|
||||||
|
|
@ -313,6 +312,7 @@ export function typeck(ast: Ast): Ast {
|
||||||
modKind,
|
modKind,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
case "extern":
|
case "extern":
|
||||||
// Nothing to check.
|
// Nothing to check.
|
||||||
return {
|
return {
|
||||||
|
|
@ -417,7 +417,7 @@ export class InferContext {
|
||||||
* before calling this.
|
* before calling this.
|
||||||
*/
|
*/
|
||||||
private constrainVar(variable: number, ty: Ty) {
|
private constrainVar(variable: number, ty: Ty) {
|
||||||
let root = this.findRoot(variable);
|
const root = this.findRoot(variable);
|
||||||
|
|
||||||
if (ty.kind === "var") {
|
if (ty.kind === "var") {
|
||||||
// Now we point our root to the other root to unify the two graphs.
|
// Now we point our root to the other root to unify the two graphs.
|
||||||
|
|
@ -571,7 +571,9 @@ export function checkBody(
|
||||||
}
|
}
|
||||||
case "let": {
|
case "let": {
|
||||||
const loweredBindingTy = expr.type && lowerAstTy(expr.type);
|
const loweredBindingTy = expr.type && lowerAstTy(expr.type);
|
||||||
let bindingTy = loweredBindingTy ? loweredBindingTy : infcx.newVar();
|
const bindingTy = loweredBindingTy
|
||||||
|
? loweredBindingTy
|
||||||
|
: infcx.newVar();
|
||||||
|
|
||||||
const rhs = this.expr(expr.rhs);
|
const rhs = this.expr(expr.rhs);
|
||||||
infcx.assign(bindingTy, rhs.ty!, expr.span);
|
infcx.assign(bindingTy, rhs.ty!, expr.span);
|
||||||
|
|
@ -772,7 +774,9 @@ export function checkBody(
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`cannot access field \`${field.value}\` on type \`${printTy(lhs.ty)}\``,
|
`cannot access field \`${field.value}\` on type \`${printTy(
|
||||||
|
lhs.ty
|
||||||
|
)}\``,
|
||||||
expr.span
|
expr.span
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -854,7 +858,7 @@ export function checkBody(
|
||||||
|
|
||||||
const assignedFields = new Set();
|
const assignedFields = new Set();
|
||||||
|
|
||||||
fields.forEach(([name, field], i) => {
|
fields.forEach(([name, field]) => {
|
||||||
const fieldTy = structTy.fields.find((def) => def[0] === name.name);
|
const fieldTy = structTy.fields.find((def) => def[0] === name.name);
|
||||||
if (!fieldTy) {
|
if (!fieldTy) {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
|
|
@ -928,8 +932,8 @@ export function checkBody(
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkBinary(expr: Expr & ExprBinary): Expr {
|
function checkBinary(expr: Expr & ExprBinary): Expr {
|
||||||
let lhsTy = expr.lhs.ty!;
|
const lhsTy = expr.lhs.ty!;
|
||||||
let rhsTy = expr.rhs.ty!;
|
const rhsTy = expr.rhs.ty!;
|
||||||
|
|
||||||
if (COMPARISON_KINDS.includes(expr.binaryKind)) {
|
if (COMPARISON_KINDS.includes(expr.binaryKind)) {
|
||||||
if (lhsTy.kind === "int" && rhsTy.kind === "int") {
|
if (lhsTy.kind === "int" && rhsTy.kind === "int") {
|
||||||
|
|
@ -969,7 +973,7 @@ function checkBinary(expr: Expr & ExprBinary): Expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkUnary(expr: Expr & ExprUnary): Expr {
|
function checkUnary(expr: Expr & ExprUnary): Expr {
|
||||||
let rhsTy = expr.rhs.ty!;
|
const rhsTy = expr.rhs.ty!;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
expr.unaryKind === "!" &&
|
expr.unaryKind === "!" &&
|
||||||
|
|
|
||||||
|
|
@ -629,12 +629,12 @@ function printStart(start: Start, f: FmtCtx) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function printElem(_elem: Elem, f: FmtCtx) {
|
function printElem(_elem: Elem, _f: FmtCtx) {
|
||||||
todo();
|
todo();
|
||||||
}
|
}
|
||||||
|
|
||||||
function printData(data: Data, f: FmtCtx) {
|
function printData(data: Data, f: FmtCtx) {
|
||||||
let mode = data.mode;
|
const mode = data.mode;
|
||||||
|
|
||||||
f.sexpr(() => {
|
f.sexpr(() => {
|
||||||
f.keyword("data");
|
f.keyword("data");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue