Home
Consulting
Advisories
Software
Articles
Contact

The Aphid Programming Language

Introduction | Try It Online | Syntax | Types | Derivatives | Download

Aphid is a multiparadigm language intended to be embedded in .NET applications or compiled into other languages like Python or PHP. The internals of Aphid are clean and easy to work with, allowing for rapid creation of derivative domain-specific languages.

Examples

Aphid is based on several languages, including Javascript, C#, and F# and has a syntax that should be familiar to most developers.

#'Std';
print('Hello, world');

The first statement, #'Std';, loads a library named Library\Std.alx. This library contains commonly used functions like print(), which is used in the subsequent statement.

Functions are declared using the function operator (@) and can be called in typical C-style manner.

#'Std';

f = @(m) {
    print(m);
};

f('Hello, world');

If a function has no parameters, the parentheses can be omitted.

#'Std';

f = @{
    print('Hello, world');
};

f();

The lambda expressions offer a more concise syntax for functions comprised of a single expression.

#'Std';
square = @(x) x * x;
print(square(5));

Rather than nesting calls, the pipeline operator (|>) can be used to write cleaner code.

#'Std';
square = @(x) x * x;
5 |> square |> print;

Partial function application can be used to pipeline functions that accept multiple arguments.

#'Std';
add = @(x, y) x + y;
5 |> @add(10) |> print;

When pipelining directly to a function or partial function, pipeline operator can be inferred.

#'Std';
add = @(x, y) x + y;
5 @add(10) |> print;

Frontends

Creating a derivative of Aphid is as simple as creating a new frontend that compiles or interprets the abstract syntax tree. Apart from the core interpreter, several frontends have been created to target a variety of languages and domains. Here are a few.

Coywolf

A frontend for Aphid that emits PHP. Create PHP applications that make use of Aphid's lightweight syntax and powerful functional capabilities.

Here's a simple Coywolf program:

<%
    #'Query';
    square = @(x) x * x;    
    [ 0, 1, 3, 4 ] @select(square) @concat(', ') |> echo;
%>

And it's compiled into PHP like this:

<?php
$square = function ($x) {
    return ($x * $x);
};
echo call_user_func(
    (function($id_00000003) use (&$concat) { return $concat(", ", $id_00000003); }),
    call_user_func(
        (function($id_00000004) use (&$select, &$square) { return $select($square, $id_00000004); }),
        [0, 1, 3, 4]));
?>

AphidHDL

AphidHDL (short for Aphid Hardware Descriptor Language) is a derivative that targets Verilog that adds a type system with struct support, among other things. As an example here's an SPI slave design:

SpiSlave = @(
	param bufferSize = byte,
	input wire sck,
	input wire ss,
	input wire mosi,
	output reg bufferSize mosiBuffer,
	input wire bufferSize misoBuffer,
	output reg miso,
	output reg shiftComplete
) {
	word bitNumber = 0;

	@(posedge sck) if (~ss) {
		mosiBuffer = [ mosiBuffer[bufferSize - 2 .. 0], mosi ];

		if (bitNumber != bufferSize - 1) {
			bitNumber++;
			shiftComplete = false;
		} else {				
			bitNumber = 0;
			shiftComplete = true;
		}
	} else {
		bitNumber = 0;
		mosiBuffer = 0;
		shiftComplete = false;
	};
	
	@(negedge sck) miso = ~ss ? misoBuffer[bufferSize - 1 - bitNumber] : 0;
};

And is compiled into Verilog that looks something like this:

module SpiSlave #(
  parameter bufferSize = 8
)(
  input wire sck,
  input wire ss,
  input wire mosi,
  output reg [bufferSize - 1:0] mosiBuffer,
  input wire [bufferSize - 1:0] misoBuffer,
  output reg miso,
  output reg shiftComplete
);
  reg [15:0] bitNumber = 0;
  always @(posedge sck)
    begin
      if (~(ss))
        begin
          mosiBuffer <= { mosiBuffer[(bufferSize - 2) : 0], mosi };
          if ((bitNumber != (bufferSize - 1)))
            begin
              bitNumber <= bitNumber + 1;
              shiftComplete <= 0;
            end
          else
            begin
              bitNumber <= 0;
              shiftComplete <= 1;
            end
        end
      else
        begin
          bitNumber <= 0;
          mosiBuffer <= 0;
          shiftComplete <= 0;
        end
    end

  always @(negedge sck)
    begin
      miso <= ~(ss) ? misoBuffer[((bufferSize - 1) - bitNumber)] : 0;
    end

endmodule




Copyright © 2018 AutoSec Tools LLC