# CODE REVIEW 2017 Challenge: Entries

Update: no one entered on time, but as I've seen at least one question on main site meeting the requirements, I'll be extending the entry date to the end of this week (23:59:59 UTC+0000 on 8 December 2017), provided you posted the question on the main site before the deadline of Thursday, 30 November 2017 at 23:59:59 UTC+0000.

The CODE REVIEW 2017 Challenge was selected last night, I've attached the details of the winning challenge below.

To enter the challenge, simply post your entry as an answer to this question. The challenge ends on Thursday, 30 November 2017 23:59:59 UTC+0000, all entries must be submitted by then.

To enter, you simply need to follow all the rules below.

• Complete all required portions of the selected challenge;
• Post the implementation of the challenge as a question on the main-site tagged ;
• Post an answer to this entry question;
• Include a link to the main site question in the answer to the entry form;

# Write your own programming language

Since we're writing a language, it's always good to know that it works. And so to score each point that adds additional features requires a unit test. All unit test must be provided for you to score the point. To allow all languages to do this, you can verify the programs output in the language you're writing in. And so if you were to write your language in the Python programming language having a unit test such as the following would be valid:

import unittest

class TestStandardArithmetic(unittest.TestCase):
# Replace eval with how you run your code
self.assertEqual(eval('1 + 1'), 2)


## Requirements

• You won't be scored for any use of eval that's provided by your language. Posting input() as your language, and requiring Python 2 is a valid language, however will score you no points.

• When scoring each point, you must use your own implementation for that point to score the point. This allows you to use, say, the LLVM to implement tail recursion in your language by default, however when scoring the point for tail recursion, you have to use your own implementation of it rather than the one provided to you by the LLVM.

• Another person must be able to verify your language works. And so make it runnable from either Windows, Linux, Mac, or via a website.

If it needs another program to run, such as CPython, the JVM, or a browser, that is fine. But it must be runnable on one of the above systems, or via a website. You must detail the requirements if a non-standard system is required.

Since to do this we need to be able to get either a binary, or your code, entries need to produce a GitHub, or any other code sharing service, repository for their language. This allows entries to write Code Review questions on what they want reviewed, rather than a new question of their entire code on each change.

This repository must be provided in the entry meta question on your entry.

## Scoring

Each bullet point is worth one point. 'Functions' may be prefix, infix or postfix operators, normal functions, or any other method that's usable in your language.

For each bullet point that adds an additional function or feature write a test case/suite with at least one unit test for each additional function or feature.

• Implement all standard operators/functions. (1 point)

• addition (+)
• subtraction (-)
• multiplication (*)
• division (/)
• less than (<)
• less than or equal (<=)
• greater than (>)
• greater than or equal (>=)
• equal (==)
• not equal (!=)
• binary or (|)
• binary xor (^)
• binary and (&)
• binary invert (~)
• binary left shift (<<)
• binary right shift (>>)
• boolean and (&&)
• boolean or (||)
• Implement operator precedence. Perform, say, multiplication and division before addition and subtraction. (1 point)
• Use lexical analysis to generate a token stream. (1 point)
• Use syntactic analysis to generate an AST, or related structure. (1 point)
• Have your language be directly interpreted. (1 point)
• Have your language compile to an intermediate language. (1 point)
• Have your language compile to an intermediate language and then be executed by a 'virtual machine'. Your intermediate language must be custom-made in order to gain this point. (1 point)
• Have your language compile directly to assembly. (1 point)
• Write a Code Review question in your language. (1 point)

Total: 9 points

In addition to the above you may also get points for implementing programming paradigms, according to Scoring of paradigm support. A big thanks to CAD97 for making such a large list, anyone can add to.

• "Implement operator precedence". That's not really possible in a prefix-/postfix- language, e.g. (+ 1 2 (- 3 4 5 6)). Will they automatically get or lose a point? – Zeta Sep 1 '17 at 12:51
• @Zeta We had 3 months to ask these questions. However, if you don't implement it you don't get the point - there are no ways to lose points, just not gain them. – Peilonrayz Sep 1 '17 at 13:37
• It's worth noting that the bulk of the points are in the paradigm support, not in this list. – mdfst13 Sep 3 '17 at 6:10
• @Peilonrayz That question has been asked but wasn't addressed – Justin Sep 3 '17 at 19:22
• @Justin I thought I did, "I'm in favour for not giving the point". I just didn't want to write the same thing twice. – Peilonrayz Sep 3 '17 at 22:21
• @Peilonrayz Ahh, thought you were referring to just the one comment. Ty for clarifying – Justin Sep 4 '17 at 2:01
• I would suggest pinning the link to my paradigm scoring to the latest commit. That way I can't edit the contents and give anyone an unfair (dis)advantage. I can't suggest the edit because meta. – CAD97 Sep 4 '17 at 23:31
• Cool, I hope to find time to join in :) – Icepickle Sep 8 '17 at 9:23
• Something that doesn't seem pinned down: what about embedded languages? I could embed a language within another (e.g. C++) and implement the entire runtime for the language. The main step that's unneeded with this approach is any sort of parsing. – Justin Sep 26 '17 at 5:52
• @Justin: That's not the usual definition of an "Embedded" language. – Martin York Sep 27 '17 at 20:09
• @LokiAstari I was meaning to talk about languages such as embedded DSLs, but not necessarily domain specific. – Justin Sep 27 '17 at 20:09
• So the real total is 48 possible points? – Martin York Sep 27 '17 at 20:10
• @Justin: Embedded usually means as part of an application or device. How would you embed another language in C++ (apart from C). Are you taking about a subset (a subset of a language is still the original language). Also I would expect any new language to use an existing runtime library (anything you can compile on to the JVM can use any of the existing Java runtime which would save a lot of time). – Martin York Sep 27 '17 at 20:13
• Are there any submissions yet? – Martin York Oct 12 '17 at 23:33
• We may have underestimated the amount of work creating a language is. Nobody has yet submitted an entry, although there clearly are people working on it. – Justin Nov 6 '17 at 21:43

# Nafi

I'll leave it up to the community to decide whether I have enough done to get the bounty, but I plan on continuing this project. It's been fun so far and there's no way I'm stopping yet. This is here to document what I've done so far and because it was requested for me to post this.

## Language Overview (theoretical)

Nafi is a language intended to be a scripting-like language offering the benefits of Mutability XOR Aliasing that builds its platform off of. However, being a scripting language, it is also supposed to be a higher level language than Rust aims to be, and provide niceties that are not zero-cost abstractions like those in Rust.

Nafi additionally draws concepts from , , and (and maybe a little ) to power its use case. The place where Nafi hopes to innovate is in allowing all libraries (including the standard library and keywords) to be easily translatable, and in a distributed-internet-first approach to libraries (what I think tries to do, though I've never used it).

The end target for Nafi is probably to be the embedded scripting language for a heavily user-customizable game idea that I've had brewing in my head for a few years. And also as a sandbox for me to play around in with all the random language ideas I have.

## Language Overview (practical, 2017-12-08)

As of 2017-12-08, the language implementation is in a middling state. I have fully functional the parser combinator library that I'm building my lexer and parser out of (because nom is too heavy handed, and I wanted to avoid macros (because IDE support is weakened by macros), so synom was out). I have my token library in a near-production ready-to-be-consumed state. And I have a fully functional lexer to turn a string into a vector of tokens (though it needs more tests) complete with REPL for manual experimenting.

## Scoring

### Main points

• Implement standard operators ✗
• Operator precedence ✗ (not planned)
• Use a Lexer to generate a stream of tokens ✓
• Use a Parser to generate an AST ✗
• Direct interpretation ✗
• Compile to IL ✗
• Execute IL on a custom virtual machine ✗
• Compile to ASM ✗ (not planned)
• CR question in the language ✗

Total: 1 point

### Paradigm support (only completed ones to save space)

• REPL ❓
• Literate - Arbitrary text ✓
• Block comments with /* <arbitrary text> */ are considered as whitespace

Total: 2 points

## Try it out

The nafi-lang/rust-nafi repository is where I've been doing the work for the Nafi interpreter/compiler. Other false-starts and partial thoughts can be found under the @nafi-lang organization.

To execute the lexer REPL, make sure you have rust nightly installed, clone the repository, and cargo run --package=nafi-lexer (using the nightly toolchain). (Or you can just cd lexer; cargo run.) After each line you enter will be printed back out as a stream of tokens. It's a debug output, and all on one line, because doing a pretty debug output takes up way too much vertical space and, honestly, this is a debug tool to see how the lexer is performing.

The most interesting interactions in the lexer are block comments /* comment */, because they can be arbitrarily nested (so /* /* */ */ is all one comment), and string literals, because I am going to support string interpolation using "1 + 1 = \{1+1}". As an example (manually formatted):

let example = "1 + 1 = \{1+1}"
[
Keyword(0, Let),
Whitespace(3),
Identifier(4, Identifier(0)),
Whitespace(11),
Symbol(12, EqualsSign),
Whitespace(13),
Literal(14, String(StringFragments { fragments: [
String("1 + 1 = "),
Interpolation([
Literal(25, Integer(1)),
Symbol(26, PlusSign),
Literal(27, Integer(1),
]),
]})),
]


Once I finish the parser step, I plan on experimenting with Rust on WASM to allow you to try it online.

## Some final notes

The lexer did work before the end of November. (Link is to last commit in November.) Though without literals.

Have a theoretical example program to solve Project Euler 1:

import nafi::print

function main() {
let answer = [1..1000)
.filter { it -> it % 3 == 0 || it % 5 == 0 }
.sum()