├── .gitignore
├── README.md
├── index.html
├── package.json
└── src
└── main.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | *.js
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.twitch.tv/tsoding)
2 | # CykaScript
3 |
4 | ## Quick Start
5 |
6 | ```console
7 | $ npm install
8 | $ npm run build
9 | $ browser index.html
10 | ```
11 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | My First Programming Language
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "typescripto",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "tsc --lib es6 src/main.ts"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "typescript": "^2.8.3"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | class Context {
2 | defineVar(name: string, value: number): void {
3 | this._nameTable.set(name, value)
4 | }
5 |
6 | varValue(name: string): number {
7 | return this._nameTable.get(name);
8 | }
9 |
10 | print(value: number): void {
11 | this._log.push(value + "")
12 | }
13 |
14 | stdout(): Array {
15 | return this._log;
16 | }
17 |
18 | pushScope(): void {
19 | }
20 |
21 | popScope(): void {
22 | }
23 |
24 | private _log = new Array();
25 | private _nameTable = new Map();
26 | }
27 |
28 | interface AstNode {
29 | eval(context: Context): T
30 | }
31 |
32 | class For implements AstNode {
33 | constructor(private _lower: AstNode,
34 | private _upper: AstNode,
35 | private _iter: string,
36 | private _body: AstNode) {
37 | }
38 |
39 | eval(context: Context) {
40 | let lower = this._lower.eval(context);
41 | let upper = this._upper.eval(context);
42 |
43 | context.pushScope();
44 | context.defineVar(this._iter, lower);
45 | for (let i = lower; i <= upper; ++i) {
46 | context.defineVar(this._iter, i);
47 | this._body.eval(context);
48 | }
49 | context.popScope();
50 | }
51 | }
52 |
53 | class Print implements AstNode {
54 | constructor(private _value: AstNode) {
55 | }
56 |
57 | eval(context: Context): void {
58 | context.print(this._value.eval(context));
59 | }
60 | }
61 |
62 | class Block implements AstNode {
63 | constructor(private _statements: Array>) {
64 | }
65 |
66 | eval(context: Context): void {
67 | context.pushScope();
68 | this._statements.forEach((statement) => {
69 | statement.eval(context)
70 | })
71 | context.popScope();
72 | }
73 | }
74 |
75 | class AssignVar implements AstNode {
76 | constructor(private _name: string,
77 | private _value: AstNode) {
78 | }
79 |
80 | eval(context: Context): void {
81 | context.defineVar(this._name, this._value.eval(context));
82 | }
83 | }
84 |
85 | class Var implements AstNode {
86 | constructor(private _name: string) {
87 | }
88 |
89 | eval(context: Context): number {
90 | return context.varValue(this._name);
91 | }
92 | }
93 |
94 | class Plus implements AstNode {
95 | constructor(private _left: AstNode,
96 | private _right: AstNode) {
97 | }
98 |
99 | eval(context: Context): number {
100 | return this._left.eval(context) + this._right.eval(context);
101 | }
102 | }
103 |
104 | class Multiply implements AstNode {
105 | constructor(private _left: AstNode,
106 | private _right: AstNode) {
107 | }
108 |
109 | eval(context: Context): number {
110 | return this._left.eval(context) * this._right.eval(context);
111 | }
112 | }
113 |
114 | class NumberLiteral implements AstNode {
115 | constructor(private _value: number) {
116 | }
117 |
118 | eval(context: Context): number {
119 | return this._value
120 | }
121 | }
122 |
123 | let context = new Context()
124 | let program = new Block([
125 | new AssignVar("x", new Plus(
126 | new NumberLiteral(5),
127 | new Multiply(
128 | new NumberLiteral(2),
129 | new NumberLiteral(10)
130 | )
131 | )),
132 | new For(new NumberLiteral(1),
133 | new NumberLiteral(10),
134 | "i",
135 | new Block([
136 | new AssignVar("x", new Plus(
137 | new Var("x"),
138 | new NumberLiteral(2)
139 | )),
140 | new Print(new Var("x"))
141 | ]))
142 | ])
143 |
144 | program.eval(context);
145 |
146 |
--------------------------------------------------------------------------------