Skip to content

Commit

Permalink
Merge pull request #66 from wcho21/dev
Browse files Browse the repository at this point in the history
release 0.2.1
  • Loading branch information
wcho21 authored Feb 11, 2024
2 parents 25f6b81 + 989efdc commit bf38241
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 10 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
_KALANG: Korean Programming Language_.

- < 0.03 MB.
- Tested with >250 cases
- Written in JavaScript, natively runs on web browsers.
- Tested with >250 cases.
- JavaScript-implemented, which runs natively on web browsers.
- Minimal syntax with Korean keywords.

Try _KALANG_ at [Playground][playground].
Expand Down Expand Up @@ -81,7 +81,7 @@ Defining and calling function:
```
which yields `52`.

Closure:
Closure and currying:
```
더하기 = 함수(숫자1) {
결과 함수(숫자2) {
Expand All @@ -92,8 +92,10 @@ Closure:
하나더하기 = 더하기(1)
하나더하기(42)
더하기(1)(42)
```
which yields `43`.
which yields `43` twice.



Expand Down
2 changes: 1 addition & 1 deletion dist/index.min.js

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions docs/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ kal.execute("쓰기('사과')", stdout => stdouts.push(stdout)); // stdout === [
```
결과는 `52`입니다.

클로저:
클로저 및 커링:
```
더하기 = 함수(숫자1) {
결과 함수(숫자2) {
Expand All @@ -94,8 +94,10 @@ kal.execute("쓰기('사과')", stdout => stdouts.push(stdout)); // stdout === [
하나더하기 = 더하기(1)
하나더하기(42)
더하기(1)(42)
```
결과는 `42`입니다.
결과는 둘 다 `42`입니다.



Expand Down
5 changes: 5 additions & 0 deletions src/evaluator/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ describe("evaluate()", () => {
input: "더하기 = 함수(숫자1) { 결과 함수(숫자2) { 결과 숫자1+숫자2 } } 하나더하기 = 더하기(1) 하나더하기(4)",
expected: 5,
},
{
name: "curried function call",
input: "더하기 = 함수(숫자1) { 결과 함수(숫자2) { 결과 숫자1+숫자2 } } 더하기(4)(7)",
expected: 11,
},
];

it.each(cases)("evaluate $name", testEvaluatingPrimitive);
Expand Down
12 changes: 12 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,15 @@ it("execute builtin function 쓰기()", () => {

expect(stdouts).toEqual(["사과", "포도 바나나"]);
});

it("execute function", () => {
expect(execute("사과 = 함수(포도) { 결과 포도+1 } 사과(42)")).toBe("43");
});

it("execute closure", () => {
expect(execute("사과 = 함수(포도) { 결과 함수(바나나) { 결과 포도 + 바나나 } } 수박 = 사과(42) 수박(99)")).toBe("141");
});

it("execute curried function", () => {
expect(execute("사과 = 함수(포도) { 결과 함수(바나나) { 결과 포도 + 바나나 } } 사과(42)(99)")).toBe("141");
});
69 changes: 69 additions & 0 deletions src/lexer/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,75 @@ describe("getSourceToken()", () => {
},
]
},
{
input: "사과(1)(2)",
expectedTokens: [
{
type: "identifier",
value: "사과",
range: {
begin: { row: 0, col: 0 },
end: { row: 0, col: 1 },
},
},
{
type: "group delimiter",
value: "(",
range: {
begin: { row: 0, col: 2 },
end: { row: 0, col: 2 },
},
},
{
type: "number literal",
value: "1",
range: {
begin: { row: 0, col: 3 },
end: { row: 0, col: 3 },
},
},
{
type: "group delimiter",
value: ")",
range: {
begin: { row: 0, col: 4 },
end: { row: 0, col: 4 },
},
},
{
type: "group delimiter",
value: "(",
range: {
begin: { row: 0, col: 5 },
end: { row: 0, col: 5 },
},
},
{
type: "number literal",
value: "2",
range: {
begin: { row: 0, col: 6 },
end: { row: 0, col: 6 },
},
},
{
type: "group delimiter",
value: ")",
range: {
begin: { row: 0, col: 7 },
end: { row: 0, col: 7 },
},
},
{
type: "end",
value: "$end",
range: {
begin: { row: 0, col: 8 },
end: { row: 0, col: 8 },
},
},
]
},
];

it.each(cases)("get tokens from input '$input'", ({ input, expectedTokens }) => {
Expand Down
34 changes: 34 additions & 0 deletions src/parser/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,40 @@ describe("parseSource()", () => {
],
},
},
{
name: "call curried function",
input: "사과(1)(2)",
expected: {
type: "program",
statements: [
{
type: "expression statement",
expression: {
type: "call",
func: {
type: "call",
func: {
type: "identifier",
value: "사과",
},
args: [
{
type: "number",
value: 1,
},
],
},
args: [
{
type: "number",
value: 2,
},
],
},
},
],
},
},
];

it.each(cases)("$name", testSuccess);
Expand Down
4 changes: 2 additions & 2 deletions src/parser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export default class Parser {
const { type, value } = this.reader.read();

if (type === "group delimiter" && value === "(") {
if (left.type !== "function" && left.type !== "identifier") {
if (left.type !== "function" && left.type !== "identifier" && left.type !== "call") {
return null;
}

Expand All @@ -202,7 +202,7 @@ export default class Parser {
return null;
}

private parseCall(left: Node.FunctionNode | Node.IdentifierNode): Node.CallNode {
private parseCall(left: Node.FunctionNode | Node.IdentifierNode | Node.CallNode): Node.CallNode {
this.advanceOrThrow("group delimiter", "(", BadGroupDelimiterError);

const secondToken = this.reader.read();
Expand Down
2 changes: 1 addition & 1 deletion src/parser/syntax-node/expression/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export interface FunctionNode extends SyntaxNodeBase<"function"> {
body: BlockNode,
};
export interface CallNode extends SyntaxNodeBase<"call"> {
func: IdentifierNode | FunctionNode,
func: IdentifierNode | FunctionNode | CallNode,
args: ExpressionNode[],
};
export interface AssignmentNode extends SyntaxNodeBase<"assignment"> {
Expand Down

0 comments on commit bf38241

Please sign in to comment.