add owning method to statements

create common keyword statement class
This commit is contained in:
Dave Holoway
2020-06-25 11:43:53 +01:00
parent b0a2475696
commit f67c03bb34
20 changed files with 125 additions and 112 deletions

View File

@@ -3,12 +3,12 @@
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
*/
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const ParseProblem = require('../parsetypes/parse-problem');
const { isTypeAssignable } = require('../expression-resolver');
const { JavaType, PrimitiveType } = require('java-mti');
class AssertStatement extends Statement {
class AssertStatement extends KeywordStatement {
/** @type {ResolvedIdent} */
expression = null;
/** @type {ResolvedIdent} */

View File

@@ -4,10 +4,10 @@
* @typedef {import('../body-types').Label} Label
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../source-types').SourceType} SourceType
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
*/
const { Statement } = require("./Statement");
const ParseProblem = require('../parsetypes/parse-problem');
const { checkAssignment } = require('../expression-resolver');
class Block extends Statement {
/** @type {Statement[]} */
@@ -17,10 +17,11 @@ class Block extends Statement {
decls = null;
/**
* @param {SourceMethodLike} owner
* @param {Token} open
*/
constructor(open) {
super();
constructor(owner, open) {
super(owner);
this.open = open;
}

View File

@@ -1,28 +1,21 @@
/**
* @typedef {import('../tokenizer').Token} Token
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
*/
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const ParseProblem = require('../parsetypes/parse-problem');
class BreakStatement extends Statement {
class BreakStatement extends KeywordStatement {
/** @type {Token} */
target = null;
/**
* @param {Token} token
*/
constructor(token) {
super();
this.break_token = token;
}
/**
* @param {ValidateInfo} vi
*/
validate(vi) {
if (!vi.statementStack.find(s => /^(for|do|while|switch)$/.test(s))) {
vi.problems.push(ParseProblem.Error(this.break_token, `break can only be specified inside loop/switch statements`));
vi.problems.push(ParseProblem.Error(this.keyword, `break can only be specified inside loop/switch statements`));
}
}
}

View File

@@ -1,28 +1,21 @@
/**
* @typedef {import('../tokenizer').Token} Token
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
*/
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const ParseProblem = require('../parsetypes/parse-problem');
class ContinueStatement extends Statement {
class ContinueStatement extends KeywordStatement {
/** @type {Token} */
target = null;
/**
* @param {Token} token
*/
constructor(token) {
super();
this.continue_token = token;
}
/**
* @param {ValidateInfo} vi
*/
validate(vi) {
if (!vi.statementStack.find(s => /^(for|do|while)$/.test(s))) {
vi.problems.push(ParseProblem.Error(this.continue_token, `continue can only be specified inside loop statements`));
vi.problems.push(ParseProblem.Error(this.keyword, `continue can only be specified inside loop statements`));
}
}
}

View File

@@ -5,10 +5,10 @@
* @typedef {import('../expressiontypes/Expression').Expression} Expression
* @typedef {import('../statementtypes/Block').Block} Block
*/
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const { checkBooleanBranchCondition } = require('../expression-resolver');
class DoStatement extends Statement {
class DoStatement extends KeywordStatement {
/** @type {ResolvedIdent} */
test = null;
/** @type {Block} */

View File

@@ -3,6 +3,7 @@
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../expressiontypes/Expression').Expression} Expression
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
*/
const { Statement } = require("./Statement");
const { BinaryOpExpression } = require('../expressiontypes/BinaryOpExpression');
@@ -13,10 +14,11 @@ const ParseProblem = require('../parsetypes/parse-problem');
class ExpressionStatement extends Statement {
/**
* @param {SourceMethodLike} owner
* @param {ResolvedIdent} expression
*/
constructor(expression) {
super();
constructor(owner, expression) {
super(owner);
this.expression = expression;
}

View File

@@ -1,13 +1,14 @@
/**
* @typedef {import('./Statement').Statement} Statement
* @typedef {import('../body-types').Local} Local
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../tokenizer').Token} Token
*/
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const { checkNonVarDeclStatement } = require('../statement-validater');
class ForStatement extends Statement {
class ForStatement extends KeywordStatement {
/** @type {ResolvedIdent[] | Local[]} */
init = null;
/** @type {ResolvedIdent} */

View File

@@ -1,12 +1,13 @@
/**
* @typedef {import('./Statement').Statement} Statement
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
*/
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const { checkBooleanBranchCondition } = require('../expression-resolver');
const { checkNonVarDeclStatement } = require('../statement-validater');
class IfStatement extends Statement {
class IfStatement extends KeywordStatement {
/** @type {ResolvedIdent} */
test = null;
/** @type {Statement} */

View File

@@ -1,15 +1,16 @@
/**
* @typedef {import('../tokenizer').Token} Token
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
*/
const { Statement } = require("./Statement");
class InvalidStatement extends Statement {
/**
*
* @param {SourceMethodLike} owner
* @param {Token} token
*/
constructor(token) {
super();
constructor(owner, token) {
super(owner);
this.token = token;
}
}

View File

@@ -0,0 +1,22 @@
/**
* @typedef {import('../tokenizer').Token} Token
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
*/
const { Statement } = require("./Statement");
/**
* A statement that begins with a keyword (if, do, while, etc)
*/
class KeywordStatement extends Statement {
/**
* @param {SourceMethodLike} owner
* @param {Token} keyword
*/
constructor(owner, keyword) {
super(owner);
this.keyword = keyword;
}
}
exports.KeywordStatement = KeywordStatement;

View File

@@ -4,6 +4,7 @@
* @typedef {import('../body-types').Label} Label
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../source-types').SourceType} SourceType
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
*/
const { Statement } = require("./Statement");
const ParseProblem = require('../parsetypes/parse-problem');
@@ -11,10 +12,11 @@ const { checkAssignment } = require('../expression-resolver');
class LocalDeclStatement extends Statement {
/**
* @param {SourceMethodLike} owner
* @param {Local[]} locals
*/
constructor(locals) {
super();
constructor(owner, locals) {
super(owner);
this.locals = locals;
}

View File

@@ -2,27 +2,20 @@
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../body-types').ResolvedValue} ResolvedValue
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
* @typedef {import('../tokenizer').Token} Token
*/
const { JavaType, PrimitiveType } = require('java-mti');
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const ParseProblem = require('../parsetypes/parse-problem');
const { isTypeAssignable } = require('../expression-resolver');
const { NumberLiteral } = require('../expressiontypes/literals/Number');
const { LambdaType, MultiValueType } = require('../anys');
class ReturnStatement extends Statement {
class ReturnStatement extends KeywordStatement {
/** @type {ResolvedIdent} */
expression = null;
/**
* @param {Token} return_token
*/
constructor(return_token) {
super();
this.return_token = return_token;
}
/**
* @param {ValidateInfo} vi
*/
@@ -30,7 +23,7 @@ class ReturnStatement extends Statement {
const method_return_type = vi.method.returnType;
if (!this.expression) {
if (method_return_type !== PrimitiveType.map.V) {
vi.problems.push(ParseProblem.Error(this.return_token, `Method must return a value of type '${method_return_type.fullyDottedTypeName}'`));
vi.problems.push(ParseProblem.Error(this.keyword, `Method must return a value of type '${method_return_type.fullyDottedTypeName}'`));
}
return;
}

View File

@@ -1,7 +1,17 @@
/**
* @typedef {import('../source-types').SourceMethodLike} SourceMethodLike
*/
class Statement {
validate(vi) {}
/**
* @param {SourceMethodLike} owner
*/
constructor(owner) {
this.owner = owner;
}
validate(vi) {}
}
exports.Statement = Statement;

View File

@@ -1,15 +1,16 @@
/**
* @typedef {import('./Statement').Statement} Statement
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../tokenizer').Token} Token
*/
const { JavaType, PrimitiveType } = require('java-mti');
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const ParseProblem = require('../parsetypes/parse-problem');
const { isTypeAssignable } = require('../expression-resolver');
const { NumberLiteral } = require('../expressiontypes/literals/Number');
class SwitchStatement extends Statement {
class SwitchStatement extends KeywordStatement {
/** @type {ResolvedIdent} */
test = null;
/** @type {(ResolvedIdent|boolean)[]} */

View File

@@ -1,12 +1,13 @@
/**
* @typedef {import('./Statement').Statement} Statement
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
*/
const { CEIType } = require('java-mti');
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const ParseProblem = require('../parsetypes/parse-problem');
class SynchronizedStatement extends Statement {
class SynchronizedStatement extends KeywordStatement {
/** @type {ResolvedIdent} */
expression = null;
/** @type {Statement} */

View File

@@ -3,11 +3,11 @@
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
*/
const { JavaType } = require('java-mti');
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const { isTypeAssignable } = require('../expression-resolver');
const ParseProblem = require('../parsetypes/parse-problem');
class ThrowStatement extends Statement {
class ThrowStatement extends KeywordStatement {
/** @type {ResolvedIdent} */
expression = null;

View File

@@ -3,11 +3,10 @@
* @typedef {import('./Block').Block} Block
* @typedef {import('../body-types').Local} Local
*/
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const { ResolvedIdent } = require('../body-types');
const ParseProblem = require('../parsetypes/parse-problem');
class TryStatement extends Statement {
class TryStatement extends KeywordStatement {
/** @type {(ResolvedIdent|Local[])[]} */
resources = [];
/** @type {Block} */

View File

@@ -1,11 +1,12 @@
/**
* @typedef {import('./Statement').Statement} Statement
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo
*/
const { Statement } = require("./Statement");
const { KeywordStatement } = require("./KeywordStatement");
const { checkBooleanBranchCondition } = require('../expression-resolver');
class WhileStatement extends Statement {
class WhileStatement extends KeywordStatement {
/** @type {ResolvedIdent} */
test = null;
/** @type {Statement} */