Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit return keyword #208

Merged
merged 4 commits into from Apr 13, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 24 additions & 3 deletions LANGUAGE.md
Expand Up @@ -48,7 +48,7 @@ Should dogescript be ported to other languages, the `js` portion may be changed

The following tokens are dogescript keywords and may not be used as *Identifiers* in dogescript programs:

 **_  and   as   bigger   biggerish   bigify   but   debooger   dose   few   giv   is   levl   less   lots   loud   many   maybe   more   much   next   not   notrly   or   pawse   plz   quiet   rly   shh   smaller   smallerish   smallify   so   such   trained   very   woof   wow  _**
 **_  amaze   and   as   bigger   biggerish   bigify   but   debooger   dose   few   giv   is   levl   less   lots   loud   many   maybe   more   much   next   not   notrly   or   pawse   plz   quiet   rly   shh   smaller   smallerish   smallify   so   such   trained   very   woof   wow  _**

Additionally, the following symbols should not be used as *Identifiers*:

Expand Down Expand Up @@ -93,7 +93,11 @@ The following are the supported assignment operators:

## Blocks

Blocks in dogescript behave the same as with javascript, however all blocks end with `wow`. Functions that return values can use `wow [val]` to return the value.
Blocks in dogescript behave the same as with javascript, however all blocks end with `wow`.

Functions that return values can use `wow [val]` or `amaze [val]` to return the value.

### wow

A block without a return would have the following syntax:
```dogescript
Expand Down Expand Up @@ -127,7 +131,7 @@ var canvas = d3.select('body')
```

The `wow&` operator is used to terminate a block that is passed in as an argument to a call, effectively taking the place of `})`:
```
```dogescript
so http
http dose createServer with much req res
res dose writeHead with 200 {'Content-Type': 'text/plain'}
Expand All @@ -148,6 +152,23 @@ http.createServer(function(req, res) {
.listen(8080);
```

### amaze
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this section should be moved to under Functions

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that makes sense.


The `amaze` keyword can be used to return a value, without closing the block.

```dogescript
such foo
amaze 'bar'
wow
```

Becomes:
```javascript
function foo() {
return 'bar';
}
```

## Functions

### Declaration
Expand Down
37 changes: 36 additions & 1 deletion lib/parser.js
Expand Up @@ -105,7 +105,8 @@ var valid = [
'obj', // can be handled as top-level token
'giv',
'levl',
'next'
'next',
'amaze'
];

/**
Expand Down Expand Up @@ -1115,6 +1116,36 @@ function handleLevl(parseContext)
return `[${tokens.shift()}]`;
}

/**
* Handles explicit return:
* amaze <expression>
*
* Produces:
* return <expression>;
*/
function handleAmaze(parseContext) {
expectToken('amaze', parseContext);

// consume: amaze
parseContext.tokens.shift();

return "return " + returnStatements(parseContext);
}

/**
* Appends statements from the parse context into a single line
*/
function returnStatements(parseContext)
{
var statement = parseStatements(parseContext);
if(shouldCloseStatement(parseContext, statement))
{
statement += ';\n';
}

return statement;
}

function parseStatement(parseContext) {

var tokens = parseContext.tokens;
Expand Down Expand Up @@ -1306,6 +1337,10 @@ function parseStatement(parseContext) {
return handleLevl(parseContext);
}

if (tokens[0] === 'amaze') {
return handleAmaze(parseContext);
}

var statement = tokens.shift();
// if there's more tokens, split them by a ' ' similar to how joinTokens would work
if(tokens.length > 0)
Expand Down
3 changes: 3 additions & 0 deletions test/spec/amaze/function-call/expect.js
@@ -0,0 +1,3 @@
function foo() {
return bar();
}
3 changes: 3 additions & 0 deletions test/spec/amaze/function-call/source.djs
@@ -0,0 +1,3 @@
such foo
amaze plz bar
wow
8 changes: 8 additions & 0 deletions test/spec/amaze/function-early-return/expect.js
@@ -0,0 +1,8 @@
function foo() {

if (bar === '') {
return;
}

baz();
}
8 changes: 8 additions & 0 deletions test/spec/amaze/function-early-return/source.djs
@@ -0,0 +1,8 @@
such foo

rly bar is ''
amaze
wow

plz baz
wow
6 changes: 6 additions & 0 deletions test/spec/amaze/in-lambda/expect.js
@@ -0,0 +1,6 @@
foo(function(n) {
if (n < 0) {
return 0;
}
return n;
})
6 changes: 6 additions & 0 deletions test/spec/amaze/in-lambda/source.djs
@@ -0,0 +1,6 @@
plz foo with much n
rly n smaller 0
amaze 0
wow
amaze n
wow&
3 changes: 3 additions & 0 deletions test/spec/amaze/single-expression/expect.js
@@ -0,0 +1,3 @@
function add(a, b) {
return a + b;
}
3 changes: 3 additions & 0 deletions test/spec/amaze/single-expression/source.djs
@@ -0,0 +1,3 @@
such add much a b
amaze a + b
wow
3 changes: 3 additions & 0 deletions test/spec/amaze/single-value/expect.js
@@ -0,0 +1,3 @@
function foo() {
return 'bar';
}
3 changes: 3 additions & 0 deletions test/spec/amaze/single-value/source.djs
@@ -0,0 +1,3 @@
such foo
amaze 'bar'
wow