diff --git a/index.ts b/index.ts index f6dde36596544331ef00c017aa362b70d6da5c2f..0881fc09c60f8aaa19652bb46c08508ad492c00f 100644 --- a/index.ts +++ b/index.ts @@ -19,6 +19,4 @@ function main() { console.log(varName, result.value, result.unit.value); } } -main(); - -//let blabla = b / f + g + 1[km/s]; +main(); \ No newline at end of file diff --git a/src/evaluateVisitor.ts b/src/evaluateVisitor.ts index 8961add47f0caedb89d2c0cd41cf7030a63f63b9..5250a461947e6fdeab1ca684655747ba8e48ae75 100644 --- a/src/evaluateVisitor.ts +++ b/src/evaluateVisitor.ts @@ -55,7 +55,7 @@ export class EvaluateVisitor implements AbstractVisitor { // 1.3.1. Cast the node to type `GroupExpr`. node = node as GroupExpr; // 1.3.2. Return the result of visiting the child `subExpr` of the node. - this.visit(node.subExpr); + return this.visit(node.subExpr); // 1.4. If it is a measured number, then: case "MeasuredNumber": @@ -107,7 +107,7 @@ export class EvaluateVisitor implements AbstractVisitor { } case "km/h": return { - value: node.numericalValue/3.6, + value: node.numericalValue*0.2778, unit: { ...node.unit, value: "m/s" }, } case "km/s": @@ -117,12 +117,12 @@ export class EvaluateVisitor implements AbstractVisitor { } case "km/min": return { - value: node.numericalValue*16.6667, + value: node.numericalValue*16.667, unit: { ...node.unit, value: "m/s" }, } case "m/h": return { - value: node.numericalValue*0.277778, + value: node.numericalValue*0.0002778, unit: { ...node.unit, value: "m/s"}, } case "m/s": @@ -132,7 +132,7 @@ export class EvaluateVisitor implements AbstractVisitor { } case "m/min": return { - value: node.numericalValue*0.0166667, + value: node.numericalValue*0.01667, unit: { ...node.unit, value: "m/s" }, } // 1.4.2.14. Otherwise: @@ -164,7 +164,7 @@ export class EvaluateVisitor implements AbstractVisitor { } else if (node.op.value === "-") { return { value: left.value - right.value, - unit: left.unit, + unit: left.unit, }; } // 1.5.4.3. Otherwise, the operation should be prohibited, and an error is reported. @@ -182,13 +182,16 @@ export class EvaluateVisitor implements AbstractVisitor { if (node.op.value === "*") { return { value: leftNode.value * rightNode.value, - unit: leftNode.unit, + unit: leftNode.unit }; } else if (node.op.value === "/") { + if (rightNode.value === 0) { + throw new Error("Division by zero"); + } return { value: leftNode.value / rightNode.value, - unit: leftNode.unit, + unit: leftNode.unit }; } else { diff --git a/src/parser.ts b/src/parser.ts index 2583851ca1872eafb90d45d51c726783f9fec23b..968d27ecadbbb6b36c152d947e9ebff4944f01e6 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -164,7 +164,7 @@ export function parseProgram(tokens: Token[]): AstNode[] { nodeType: "PhysicalUnit" }; // 3.1.3. Otherwise, if that value is one of the mass units, then: - } else if (["g", "kg"]) { + } else if (["g", "kg"].includes(unitValue)) { // 3.1.3.1. Return an object with the following properties: return { // 3.1.3.1.1. Property `value` should be the value of the token, casted to type `Mass` @@ -176,7 +176,7 @@ export function parseProgram(tokens: Token[]): AstNode[] { }; // 3.1.4. Otherwise, if that value is one of the (???what???) units, then: - } else if (["m", "km"]) { + } else if (["m", "km"].includes(unitValue)) { return { value: unitValue as Distance, kind: PhysicalUnitEnum.Distance, @@ -184,7 +184,7 @@ export function parseProgram(tokens: Token[]): AstNode[] { } } // 3.1.5. Otherwise, if that value is one of the (???what???) units, then: - else if (["km/h", "km/s", "km/min", "m/h", "m/s", "m/min"]) { + else if (["km/h", "km/s", "km/min", "m/h", "m/s", "m/min"].includes(unitValue)) { return { value: unitValue as Velocity, kind: PhysicalUnitEnum.Velocity, @@ -222,9 +222,9 @@ export function parseProgram(tokens: Token[]): AstNode[] { // 6. Return an AST node that represents an assignment statement -- it is an object with: return { // 6.1. A property that represents the assignee (i.e., the variable that has been assigned to). - assignee, + assignee: assignee, // 6.2. A property that represents the expression on the right-hand side of the assignment statement. - expr, + expr: expr, // 6.3. A property `nodeType` which is (???what???). nodeType : "AssignmentStatement" }; @@ -240,7 +240,7 @@ export function parseProgram(tokens: Token[]): AstNode[] { ClosingBracket(); return { - subExpr, + subExpr: subExpr, nodeType: "GroupExpr" }; } @@ -274,8 +274,8 @@ export function parseProgram(tokens: Token[]): AstNode[] { let unit = PhysicalUnit(); return { - numericalValue, - unit, + numericalValue: numericalValue, + unit: unit, nodeType: "MeasuredNumber" }; } @@ -355,7 +355,7 @@ export function parseProgram(tokens: Token[]): AstNode[] { // 3. Expect (i.e., consume) that peek'ed token, and store it in a variable. let op = OpAddSub(); // 4. Expect a multiplicative expression, and store it in a variable. - let right = Multiplicative(); + let right: PrimitiveExpr | Multiplicative = Multiplicative(); // 5. Update the expression stored in item 1. to be an AST node that represents an additive expression -- it is an object with: left = { // 5.1. A property that represents the left operand of the multiplicative expression. @@ -374,7 +374,7 @@ export function parseProgram(tokens: Token[]): AstNode[] { } function Multiplicative(): Multiplicative | PrimitiveExpr { - let left: Multiplicative | PrimitiveExpr = PrimitiveExpr(); //May be a problem + let left: PrimitiveExpr | Multiplicative = PrimitiveExpr(); while (peek().kind === "OpMulDiv") { let op = OpMulDiv(); let right = PrimitiveExpr(); diff --git a/src/typeCheckVisitor.ts b/src/typeCheckVisitor.ts index 7d801fc30d04cde1a86556317aed59c7fdd64a22..b01ed9fcf07ab1cbb50f4adc8f7f5665f5c65b79 100644 --- a/src/typeCheckVisitor.ts +++ b/src/typeCheckVisitor.ts @@ -56,7 +56,12 @@ export class TypeCheckVisitor implements AbstractVisitor { // 1.5. If it is an addition-like expression, then: case "Additive": { node = node as Additive; - return this.visit(node.left); + let left = this.visit(node.left); + let right = this.visit(node.right); + if (right === left) { + return left; + } + throw new Error("Left and right not alike"); } // 1.6. It it is a multiplication-like expression, then: @@ -86,9 +91,6 @@ export class TypeCheckVisitor implements AbstractVisitor { if (left === PhysicalUnitEnum.Distance && right === PhysicalUnitEnum.Time) { return PhysicalUnitEnum.Velocity; } - if (right === 0) { - throw new Error("Division by zero"); - } } // 1.6.4.3. Otherwise, if it any other operator, report an error. throw new Error("Failure!");