This commit is contained in:
parent
21e569e9ff
commit
6620dbcace
@ -80,6 +80,8 @@ export class Node {
|
|||||||
return visit();
|
return visit();
|
||||||
case "IntExpr":
|
case "IntExpr":
|
||||||
return visit();
|
return visit();
|
||||||
|
case "ArrayExpr":
|
||||||
|
return visit(...k.values);
|
||||||
case "CallExpr":
|
case "CallExpr":
|
||||||
return visit(k.expr, ...k.args);
|
return visit(k.expr, ...k.args);
|
||||||
case "UnaryExpr":
|
case "UnaryExpr":
|
||||||
@ -115,6 +117,7 @@ export type NodeKind =
|
|||||||
| { tag: "Param"; ident: string; ty: Node | null }
|
| { tag: "Param"; ident: string; ty: Node | null }
|
||||||
| { tag: "IdentExpr"; ident: string }
|
| { tag: "IdentExpr"; ident: string }
|
||||||
| { tag: "IntExpr"; value: number }
|
| { tag: "IntExpr"; value: number }
|
||||||
|
| { tag: "ArrayExpr"; values: Node[] }
|
||||||
| { tag: "CallExpr"; expr: Node; args: Node[] }
|
| { tag: "CallExpr"; expr: Node; args: Node[] }
|
||||||
| { tag: "UnaryExpr"; op: UnaryOp; expr: Node; tok: string }
|
| { tag: "UnaryExpr"; op: UnaryOp; expr: Node; tok: string }
|
||||||
| { tag: "BinaryExpr"; op: BinaryOp; left: Node; right: Node; tok: string }
|
| { tag: "BinaryExpr"; op: BinaryOp; left: Node; right: Node; tok: string }
|
||||||
|
|||||||
@ -80,6 +80,24 @@ export class Checker {
|
|||||||
return Ty.Int;
|
return Ty.Int;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (node.is("ArrayExpr")) {
|
||||||
|
let ty: Ty | null = null;
|
||||||
|
for (const value of node.kind.values) {
|
||||||
|
const valueTy = this.check(value);
|
||||||
|
if (ty) {
|
||||||
|
this.assertCompatible(ty, valueTy, value.line);
|
||||||
|
} else {
|
||||||
|
ty = valueTy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ty) {
|
||||||
|
this.error(node.line, `could not infer type of empty array`);
|
||||||
|
this.fail();
|
||||||
|
}
|
||||||
|
const length = node.kind.values.length;
|
||||||
|
return Ty.create("Array", { ty, length });
|
||||||
|
}
|
||||||
|
|
||||||
if (node.is("CallExpr")) {
|
if (node.is("CallExpr")) {
|
||||||
return this.checkCall(node);
|
return this.checkCall(node);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -240,6 +240,19 @@ export class Parser {
|
|||||||
const expr = this.parseExpr();
|
const expr = this.parseExpr();
|
||||||
this.mustEat(")");
|
this.mustEat(")");
|
||||||
return expr;
|
return expr;
|
||||||
|
} else if (this.eat("[")) {
|
||||||
|
const values: ast.Node[] = [];
|
||||||
|
if (!this.done && !this.test("]")) {
|
||||||
|
values.push(this.parseExpr());
|
||||||
|
while (this.eat(",")) {
|
||||||
|
if (this.test("]")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
values.push(this.parseExpr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.mustEat("]");
|
||||||
|
return ast.Node.create(loc, "ArrayExpr", { values });
|
||||||
} else {
|
} else {
|
||||||
this.mustEat("<expression>");
|
this.mustEat("<expression>");
|
||||||
throw new Error();
|
throw new Error();
|
||||||
@ -318,7 +331,7 @@ export type Tok = { type: string; value: string; line: number };
|
|||||||
const keywordPattern =
|
const keywordPattern =
|
||||||
/^(?:fn)|(?:return)|(?:let)|(?:if)|(?:else)|(?:while)|(?:break)|(?:or)|(?:and)|(?:not)|(?:mut)$/;
|
/^(?:fn)|(?:return)|(?:let)|(?:if)|(?:else)|(?:while)|(?:break)|(?:or)|(?:and)|(?:not)|(?:mut)$/;
|
||||||
const operatorPattern =
|
const operatorPattern =
|
||||||
/((?:\->)|(?:==)|(?:!=)|(?:<=)|(?:>=)|(?:<<)|(?:>>)|[\n\(\)\{\}\,\.\;\:\!\=\<\>\&\^\|\+\-\*\/\%])/g;
|
/((?:\->)|(?:==)|(?:!=)|(?:<=)|(?:>=)|(?:<<)|(?:>>)|[\n\(\)\{\}\[\]\,\.\;\:\!\=\<\>\&\^\|\+\-\*\/\%])/g;
|
||||||
|
|
||||||
export function tokenize(text: string): Tok[] {
|
export function tokenize(text: string): Tok[] {
|
||||||
return text
|
return text
|
||||||
|
|||||||
@ -132,5 +132,6 @@ export type TyKind =
|
|||||||
| { tag: "Bool" }
|
| { tag: "Bool" }
|
||||||
| { tag: "Ptr"; ty: Ty }
|
| { tag: "Ptr"; ty: Ty }
|
||||||
| { tag: "PtrMut"; ty: Ty }
|
| { tag: "PtrMut"; ty: Ty }
|
||||||
|
| { tag: "Array"; ty: Ty; length: number }
|
||||||
| { tag: "Fn"; params: Ty[]; retTy: Ty }
|
| { tag: "Fn"; params: Ty[]; retTy: Ty }
|
||||||
| { tag: "FnStmt"; ty: Ty; stmt: ast.NodeWithKind<"FnStmt"> };
|
| { tag: "FnStmt"; ty: Ty; stmt: ast.NodeWithKind<"FnStmt"> };
|
||||||
|
|||||||
6
tests/_array.ethlang
Normal file
6
tests/_array.ethlang
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
fn main()
|
||||||
|
{
|
||||||
|
let array = [1, 2, 3];
|
||||||
|
}
|
||||||
|
|
||||||
@ -5,7 +5,7 @@ set -e
|
|||||||
TEST_DIR=$(dirname $0)
|
TEST_DIR=$(dirname $0)
|
||||||
SRC_DIR=$TEST_DIR/../src
|
SRC_DIR=$TEST_DIR/../src
|
||||||
|
|
||||||
TEST_SRC=$(find $TEST_DIR -name '*.ethlang')
|
TEST_SRC=$(find $TEST_DIR -name '*.ethlang' -and -not -name "_*")
|
||||||
|
|
||||||
count_total=0
|
count_total=0
|
||||||
count_succeeded=0
|
count_succeeded=0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user