Skip to content

Commit

Permalink
Add new line checks everywhere (#55)
Browse files Browse the repository at this point in the history
* add check for new lines

* comments ordering, update tests

* abstract class parse

* abstract class impl
  • Loading branch information
Kiyomi H committed Oct 14, 2019
1 parent e971752 commit efef541
Show file tree
Hide file tree
Showing 18 changed files with 100 additions and 22 deletions.
15 changes: 8 additions & 7 deletions ebnf.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
PROGRAM ::= ‘project’ (str | STRLIST) nl MODULE? nl (DIR|CLASS|INTERFACE)* nl
MODULE ::= ‘modules’ STRLIST nl # should have quotes
PROGRAM ::= ‘project’ str nl (MODULE nl)? (DIR|CLASS|INTERFACE)*
MODULE ::= ‘modules’ STRLIST # should have quotes
DIR ::= ‘dir’ str nl (ind (DIR|CLASS|INTERFACE) ded)* nl
CLASS ::= ABS? ‘class’ str IMP? EXT? (nl COMMENT)? (nl FIELD)* (nl FUNC)* nl
CLASS ::= ABS? ‘class’ str IMP? EXT? (nl COMMENT)? (nl FIELD)* (nl (FUNC | CONSTR))* nl
INTERFACE ::= ‘interface’ str EXT? (nl COMMENT)? (nl FIELD)* (nl FUNC)* nl

FIELD ::= ind ‘fields’ mod? VARLIST (nl ind 'generate' gen)* ded
FUNC ::= ind ‘function ’ mod ‘async ’? 'static'? str (nl PARAM)? (nl ind 'returns' type)? (nl ind COMMENT)? ded
FUNC ::= ind ‘function ’ mod ‘async ’? 'static'? str (nl ind COMMENT)? (nl PARAM)? (nl ind 'returns' type)? ded
CONSTR ::= ind ‘constructor’ mod (nl PARAM)? ded

PARAM ::= ind ‘params ’ VARLIST ded
COMMENT ::= ind ‘comments ’ STRLIST ded
Expand All @@ -17,10 +18,10 @@ VARLIST ::= ‘[ ’ (type str (‘,’ type str))? ‘ ]’
STRLIST ::= ‘[ ‘ str (‘,’ str)* ‘ ]’

gen ::= (‘getters’ | ‘setters’)
mod ::= ‘private’ | ‘public’| ‘protected’
mod ::= (‘private’ | ‘public’| ‘protected’)
type ::= (‘number’ | ‘boolean’| ‘string’ | str) sp
str ::= [a-z|A-Z]* sp
sp ::= ‘ ’
nl ::= [\n]
ind ::= [\t]
nl ::= [\n]+
ind ::= [\t | ]+ # tab(s) or single space(s)
ded ::= [] # this is a dedent
3 changes: 3 additions & 0 deletions src/ast/ClassDecl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export class ClassDecl extends Content {
this.className = context.getNext();

if(context.checkToken("implements")) {
if(this.isAbstract) {
throw new ParseError("Cannot implement another class in an abstract class");
}
this.implementsNodes = new ImplementsDecl();
this.implementsNodes.parse(context);
}
Expand Down
8 changes: 7 additions & 1 deletion src/ast/DirDecl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export class DirDecl extends Content {
this.directoryName = context.getNext();

this.parseContents(context);

context.checkStartOfLine();
}

protected parseContents(context: Tokenizer): any {
Expand All @@ -32,9 +34,11 @@ export class DirDecl extends Content {
while (context.getCurrentLineTabLevel() > this.tabLevel && !context.checkToken("NO_MORE_TOKENS")) {
let contentDecl: Content;

context.checkStartOfLine();

if (context.checkToken("dir")) {
contentDecl = new DirDecl(this.getAbsolutePath());
} else if (context.checkToken("class")) {
} else if (context.checkToken("class") || context.checkToken("abstract")) {
contentDecl = new ClassDecl(this.getAbsolutePath());
} else if (context.checkToken("interface")) {
contentDecl = new InterfaceDecl(this.getAbsolutePath());
Expand All @@ -44,6 +48,8 @@ export class DirDecl extends Content {

contentDecl.parse(context);
this.contents.push(contentDecl);

context.checkStartOfLine();
}
}

Expand Down
22 changes: 17 additions & 5 deletions src/ast/FuncDecl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export default class FuncDecl extends AstNode {
name: string;
params: VarList;
comments: CommentDecl;
body: string = null; // only used in getter/setter
returnDecl: ReturnDecl = new ReturnDecl();

public parse(context: Tokenizer): any {
Expand All @@ -45,17 +44,30 @@ export default class FuncDecl extends AstNode {
this.comments = new CommentDecl();

this.name = context.getNext();
if (context.checkToken("returns")) {
this.returnDecl.parse(context);

context.checkStartOfLine();

if (context.getCurrentLineTabLevel() <= indentLevel) return;
context.checkStartOfLine();

if(context.checkToken("comments")) {
this.comments.parse(context);
}

if (context.getCurrentLineTabLevel() <= indentLevel) return;
context.checkStartOfLine();

if (context.checkToken("params")) {
context.getAndCheckNext("params");
this.params.parse(context);
this.comments.parse(context);
}
this.returnDecl.parse(context);

if (context.getCurrentLineTabLevel() <= indentLevel) return;
context.checkStartOfLine();

if(context.checkToken("returns")) {
this.returnDecl.parse(context);
}
}

public evaluate(): any {
Expand Down
3 changes: 3 additions & 0 deletions src/ast/ProgramDecl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ export class ProgramDecl extends DirDecl {
this.projectName = context.getNext();
this.directoryName = this.projectName;

context.checkStartOfLine();

if (context.checkToken("modules")) {
this.modules = new ModuleDecl();
this.modules.parse(context);
context.checkStartOfLine();
}

super.parseContents(context);
Expand Down
8 changes: 7 additions & 1 deletion src/codegen/TypeScriptEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,15 @@ export default class TypeScriptEngine {
classMembers.push(this.createMethod(fn));
}

let modifiers: Modifier[] = [];
modifiers.push(ts.createModifier(SyntaxKind.ExportKeyword));
if(classDecl.isAbstract) {
modifiers.push(ts.createModifier(SyntaxKind.AbstractKeyword));
}

return ts.createClassDeclaration(
undefined,
[ts.createModifier(SyntaxKind.ExportKeyword)],
modifiers,
classDecl.className,
undefined,
this.makeHeritageClause(classDecl),
Expand Down
8 changes: 8 additions & 0 deletions test/ast/ClassDecl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,12 @@ describe ("ClassDecl evaluate test", () => {
createdFiles.push(OUTPUT_DIR + "/Time.ts");
});

it("writes an abstract class to disk", () => {
let tokenizer : Tokenizer = new Tokenizer("classDeclAbstract.txt", "./test/testFiles");
let classDec : ClassDecl = new ClassDecl(OUTPUT_DIR);
classDec.parse(tokenizer);
classDec.evaluate();
// createdFiles.push(OUTPUT_DIR + "/Time.ts");
})

});
18 changes: 18 additions & 0 deletions test/ast/DirDecl.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { expect } from "chai";
import {DirDecl} from "../../src/ast/DirDecl";
import {Tokenizer} from "../../src/util/Tokenizer";
import {ClassDecl} from "../../src/ast/ClassDecl";

describe("DirDecl parse test", () => {

const DUMMY_ROOT_DIR: string = ".";

it("parses dir with abstract class inside", () => {
let tokenizer : Tokenizer = new Tokenizer("dirDeclWithAbstractClass.txt", "./test/testFiles");
let dirDec : DirDecl = new DirDecl(DUMMY_ROOT_DIR);
dirDec.parse(tokenizer);
expect(dirDec.contents).to.have.length(1);
let classDec = dirDec.contents[0] as ClassDecl;
expect(classDec.isAbstract).to.be.true;
});
});
2 changes: 1 addition & 1 deletion test/ast/InterfaceDecl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("InterfaceDecl parse test", () => {
it("throws a ParseError with invalid line", () => {
let tokenizer : Tokenizer = new Tokenizer("interfaceInvalidInput.txt", "./test/testFiles");
let intDec : InterfaceDecl = new InterfaceDecl(".");
expect(() => {intDec.parse(tokenizer)}).to.throw(ParseError);
expect(() => {intDec.parse(tokenizer)}).to.throw(TokenizerError);

});
});
Expand Down
9 changes: 9 additions & 0 deletions test/testFiles/classDeclAbstract.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
abstract class Time extends TimeClass
comments [ "This is the time class" ]
fields private [ number dayOfWeek, number hour, number minute ]
generate getters
generate setters
fields public [ number date ]
generate getters
function public formatDate
returns string
2 changes: 1 addition & 1 deletion test/testFiles/classDeclComplex.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Time implements ITime, DateTime extends TimeClass
fields public [ number date ]
generate getters
function public getDate
params [ string id, string content, string kind ]
comments [ "creates a new Time object from given date",
"{param} date - date object to parse time object from" ]
params [ string id, string content, string kind ]
returns string
Empty file.
10 changes: 10 additions & 0 deletions test/testFiles/dirDeclWithAbstractClass.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
dir models
abstract class Time implements ITime, DateTime extends TimeClass
comments [ "This is the time class" ]
fields private [ number dayOfWeek, number hour, number minute ]
generate getters
generate setters
fields public [ number date ]
generate getters
function public getDate
returns string
2 changes: 1 addition & 1 deletion test/testFiles/funcDeclComplex.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function public static async addDataset
params [ string id, string content, InsightDatasetKind kind ]
comments [ "Add Dataset function", "returns ids of datasets on disk" ]
params [ string id, string content, InsightDatasetKind kind ]
returns Promise<string>
3 changes: 2 additions & 1 deletion test/testFiles/funcDeclOptionalParams.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
function public getTime returns number
function public getTime
returns number
3 changes: 2 additions & 1 deletion test/testFiles/funcDeclUndefinedType.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
function private foo returns NOTAVALIDTYPE
function private foo
returns NOTAVALIDTYPE
2 changes: 1 addition & 1 deletion test/testFiles/funcDeclWithComments.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function private foo
params [ ]
comments [ "ayy lmao" ]
params [ ]
returns number
4 changes: 2 additions & 2 deletions test/testFiles/interfaceDeclComplex.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
interface TransitLine
function public getNumberOfStops
params [ ]
comments [ "Returns the number of stops in the transit line" ]
params [ ]
returns number
function getRoute
params [ ]
comments [ "Returns the street names of transit route" ]
params [ ]
returns string

0 comments on commit efef541

Please sign in to comment.