How about a contest?

I'm bored and made a simple scripting language, and was wondering how other people would create languages, and what they would decide to add to the standard libraries and capabilities.
So, I decided to hold a contest.

RULES:
You can submit any work you've done in the past, or create something specifically for this.
You can submit something compiled for *nix, but you need to submit a Windows executable as well. (This helps with grading)
You can submit your project any time before New Years.
Interpreted languages are suggested, but if anyone wants to submit a compiler more power to you.

ENTRIES:
Entries must include:
-Your name
-The language's name
-Source (full or partial) OR an explanation of what you did
-Three sample programs (as language source code): Hello world, something demonstrating program flow, and a third of your choice
-A compiled executable

SCORING:
Entries are scored from 0-5 on 5 different scales:
-Simplicity: How simple the developed language is
-Functionality: What functions and abilities are provided out-of-the-box
-Legibility: How easy the developed code is to read
-Creativity: What was used to create the language
-Stability: How well it stands up to a couple of bored teens trying to break it

Is anyone interested, or are these more ramblings of someone who hasn't had enough sleep?
Last edited on
Interesting. I will be submitting my new language, called Python. You can find it at python.org


Ok, I admit it. I'm a fraud... :(

someone who hasn't had enough sleep?

You called? Last night I went to sleep at 3am and woke up and 9am. Last week I literally spent the whole night (8pm to 8am) playing halo and eating peanutbutter sandwhiches.
Last edited on
Heh, thanks for the amusing message when I wake up (with my 7 hours of sleep...which is a first, as normally I have to wake up at 5:30)

Python? Never heard of it. It looks interesting though! (xD)
chrisname wrote:
Interesting. I will be submitting my new language, called Python. You can find it at python.org


OMG! That language is so awesome! I wish I could make one like that...
This is only the definition. I'm working on the implementation.

Text Formatting Language (TFL, or Teflon).
The language uses several markup tags to provide facilities for line wrapping, justification, centering, and indentation.

Whitespace handling:
Whitespace at the beginning of a line is only modified by removing tabs according to the value of the <tab size> tag (see below). It is considered embedded indentation, and wrapped lines duplicate it.
Whitespace between words is left untouched. Only spacing is only added, never removed, except for spacing at the end of lines, which is always removed.

Tag expansion:
With two exceptions, no tag generates output. There's an exception where if a line consists solely of tags and no other whitespace (excluding the newline) or non-whitespace character is on the line, the line isn't outputted as a blank line, and is instead discarded.

Line wrapping tags:
<wrap:%>
Wraps text at the given column number. If not specified, the default is 79.

Justification tags:
<j></j>
Justifies text.
Only entire lines can be justified. Placing the opening tag in the middle of a line has the same effect as placing it at the beginning.
If used while a center block is open, the block is cancelled for the current line and closed, and the justification block is opened.

Centering tags:
<c></c>
Centers text.
Only entire lines can be centered. Placing the opening tag in the middle of a line has the same effect as placing it at the beginning.
If used while a justification block is open, the block is cancelled for the current line and closed, and the centering block is opened.

Indentation tags:
<tab size:%>
Sets the size of tabs. Tabs will be replaced in the output by no more than this many spaces (the exact number depends on the column where the tab is located, obviously).
Default is 8.

<indent size:%>
Sets the size that will be used by the <indent> and <+indent> tags.
Default is 4.

<+indent[:$]>
If the string parameter isn't provided, add one indentation level according to <indent size>.
If it is provided, add the string to the indentation stack.

<+bullet:$>
Same as <+indent>, but behaves differently with split lines:
<+indent:* >Only entire lines can be centered. Placing the opening tag in the middle of a line has the same effect as placing it at the beginning.
If used while a justification block is open, the block is cancelled for the current line and closed, and the centering block is opened.
1
2
3
4
* Only entire lines can be centered. Placing the opening tag in the middle of a
* line has the same effect as placing it at the beginning.
* If used while a justification block is open, the block is cancelled for the
* current line and closed, and the centering block is opened.

<+bullet:* >Only entire lines can be centered. Placing the opening tag in the middle of a line has the same effect as placing it at the beginning.
If used while a justification block is open, the block is cancelled for the current line and closed, and the centering block is opened.
1
2
3
4
* Only entire lines can be centered. Placing the opening tag in the middle of a
  line has the same effect as placing it at the beginning.
* If used while a justification block is open, the block is cancelled for the
  current line and closed, and the centering block is opened.


<-indent>
Pops one indentation level from the indentation stack if possible, otherwise print an error.

</indent>
Remove all indentation levels.

Other tags:
<<> <>>
Put a < or a > in the output, respectively.

<allcaps></allcaps>
The output is written in upper case only.

<end>
Stop processing. The rest of the input is directly copied to the output.

Example - Generating a BSD licence (must first be passed through m4):
define(COPYRIGHT,`2009')dnl
define(AUTHOR,`J. Random Hacker')dnl
define(PRODUCT,`void multiplier')dnl
<j><indent:* >
Copyright (c) COPYRIGHT, AUTHOR
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
<indent size:4>
<+indent><+bullet:* >
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
<-indent><-indent>

<allcaps>
This software is provided by AUTHOR "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall AUTHOR be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
</allcaps></j>
Whoa, that's...really thought out!
So the implementation's in progress? I really wanna check that out now >_> sounds like it'll be interesting!

Only one other entry? I figured that more people would be inspired/bored enough to do it...
Do emulators count? Technically they do interpret opcodes so in a sense it is interpretation...

If so;

Name: Chris
Language: Err... Hexadecimal? 8086 assembly?
Source: When I'm done
Three sample programs: That'll be kinda hard.
Compiled executable: Again, when I'm done.

Also, don't hold me to this. As yet I haven't found enough documentation (I've found some neat explanations of what each instruction does, but not what the opcodes are. As to that, I have no case labels, so I can't actually execute any code. Also, I still need to implement all the instructions that take operands (I know how to get them, but it'll be hard to act on them).

At the moment it's about 1000 lines. I'm pretty proud of it, actually; it's easily the most complex program I've written and the most code I've ever typed. Then again, it gets 115 compile-time errors if you try to build it (because I don't have any case labels, so I just have a bunch of
1
2
3
case :
goto aaa;
break;
and yes, I am using goto. Why? It's efficient.)

Also, when I fix the case labels (that is, find out what they should be) it will work on windows. And by work; I mean run. And by run, I mean go into an infinite loop and not do anything but read from the programs memory.

Also it will work on big/little endian machines I think. Edit: but you'll have to recompile it and define _BIG_ENDIAN when you do.

Edit: I also just realized I have to implement every hardware interrupt the 8086 had. :(
This just got harder...
Last edited on
You haven't found enough documentation on x86, the single most popular processor architecture in history?
http://www.intel.com/products/processor/manuals/index.htm

As for the goto, you're losing any performance you could gain from it by putting it inside a switch, which performs the equivalent to a linear search. It would actually be faster (on average) to put a bunch of function pointers in an array. something like
instruction_pointer instr[]={ mov, add, sub, div, /*...*/ };
I have found tons of docs on the x86, not the 16-bit 8086. And the only stuff I haven't found is what order the opcodes are in (I have it in alphabetical order, e.g. aaa up to xor).

Thanks for the speed info. I heard a switch was efficient if it had a lot (like 100) of case labels because it became a "jump table". I just wish I'd mentioned this before writing 637 lines of code (and that's just my horrible, horrible switch. Yes, it's evil (a 637 line switch statement. Ew.)...

1
2
3
int (* instr[])(int*) = {
    /* ... */
}

Edit: actually like above.
Edit 2: I much prefer this function array business. Thank you :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void run(register PROGRAM* program, register cpu_t* cpu) {
    register unsigned opcode    = 0,
                      counter   = 0,
                      params[2] = {0};
    cpu->registers.ip = 0
    
    for (;;) {
        opcode = program->memory[cpu->registers.ip]; /* Get an opcode */
        counter -= cycles[opcode].cycles; /* Each opcode takes up n cycles... */

        /* Call the instruction: */
        instr_set[opcode](params);

        /* Check if interrupt is expected to fire */
        if (counter <= 0) {
            counter += cpu->interrupt_period;

            /* Check we're still running the CPU. This is done when an interrupt
             * is expected as not much else would make the CPU exit. */
            if (cpu->is_running == False)
                done();
        }
    }
    
    if (program->is_open == True)
        fclose(program->fp);
}

Now this is actually legible. Again, thanks.
Last edited on
"Order"? You mean their binary representation? Any good reference should include it. Or you could use NASM (or any other assembler) to generate every possible opcode.
helios wrote:
or you could use NASM (or any other assembler) to generate every possible opcode.

For god's sake why didn't I think of that? That seems really obvious now!

And no, I haven't found anything that included it!

Also, yes. I want to know what "number" it is, e.g. 0xF4 is hlt (I think).
Then I can get the opcode byte, check if it takes params (I'll just store an array to store how many parameters an opcode takes (0, 1 or 2) to see if I need to get one or two more bytes).
Last edited on
Topic archived. No new replies allowed.