Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Help with unambiguous grammar

Name: long long 2012-01-13 22:59

I'm creating yet another fail C-family compiler.
Objectives: simple language, generics, type inference, and unambiguous grammar.
I would like to hear your opinions, any help is very appreciated.

bison parser:
%union {
    char *str;
}

%right '=' "+=" "-=" "*=" "/=" "%=" "~=" "&=" "|=" "^=" "<<=" ">>="
%left ':'
%right '?'
%left '|'
%left '^'
%left '&'
%left "or"
%left "and"
%left "==" "!="
%left '<' "<=" '>' ">="
%left "<<" ">>"
%left '+' '-'
%left '*' '/' '%'
%right "not" '~' PREFIX
%left "++" "--"
%left '['
%left '.'
%right '$'

%token <str> ID INT HEX BIN DOUBLE FLOAT COMPLEX STRING CHAR
%token-table

%%

program:
       | program import
       | program decl
       ;

import: "import" module
      | "import" module "as" identifier
      ;

module: identifier
      | module '.' identifier
      ;

decl: declvar
    | declfunc
    | declstruct
    ;

declvar: "var" identifier
       | "var" identifier '=' expr
       | "def" identifier '=' expr
       ;

declstruct: "def" identifier '{' declattrs '}'
          ;

declattrs: declattr
         | declattrs declattr
         ;

declattr: "var" identifier
        | declfunc
        ;

declfunc: "def" identifier '(' declargs ')' block
        ;

declargs: declarg
        | declargs ',' declarg
        ;

declarg: identifier
       | "var" identifier
       | identifier identifier
       ;

block: '{' '}'
     | '{' stmts '}'
     ;

stmts: stmt
     | block
     | stmts stmt
     | stmts block
     ;

stmt: declvar
    | purestmt
    | identifier ':' purestmt
    ;

purestmt: assign
        | call
        | if
        | for
        | while
        | switch
        | "goto" identifier
        | "return" expr
        ;

assign: lvalue '=' expr
      | lvalue "+=" expr
      | lvalue "-=" expr
      | lvalue "*=" expr
      | lvalue "/=" expr
      | lvalue "%=" expr
      | lvalue "~=" expr
      | lvalue "&=" expr
      | lvalue "|=" expr
      | lvalue "^=" expr
      | lvalue "<<=" expr
      | lvalue ">>=" expr
      | lvalue "++"
      | lvalue "--"
//      | "++" lvalue %prec PREFIX
//      | "--" lvalue %prec PREFIX
      ;

lvalue: identifier
      | lvalue '.' identifier
      | lvalue '[' expr ']'
      | '$' lvalue
      ;

identifier: ID
          ;

expr: literal
    | lvalue
    | assign
    | call
    | '~' expr
    | '@' lvalue
    | '-' expr %prec PREFIX
    | expr '+' expr
    | expr '-' expr
    | expr '*' expr
    | expr '/' expr
    | expr '%' expr
    | expr '&' expr
    | expr '|' expr
    | expr '^' expr
    | "not" expr
    | expr "==" expr
    | expr "!=" expr
    | expr '<' expr
    | expr "<=" expr
    | expr '>' expr
    | expr ">=" expr
    | expr "<<" expr
    | expr ">>" expr
    | expr "and" expr
    | expr "or" expr
    | expr '?' expr ':' expr
    | "proc" '(' declargs ')' block
    | '(' expr ')'
    ;

literal: INT
       | HEX
       | BIN
       | FLOAT
       | DOUBLE
       | COMPLEX
       | STRING
       | CHAR
       ;

call: onecall
    | call '.' onecall
    ;

onecall: lvalue '(' args ')'
       ;

args:
    | expr
    | args ',' expr
    ;

if: "if" '(' expr ')' block
  | "if" '(' expr ')' block "else" block
  ;

for : "for" '(' forarg "in" foriter ')' loop
    | "for" '(' forinit ';' expr ';' forincr ')' loop
    ;

forarg: identifier
      | "var" identifier
      ;

forinit: forinitarg
       | forinit ',' forinitarg
       ;

forinitarg: assign
          | "var" identifier '=' expr
          ;

forincr: assign
       | forincr ',' assign
       ;

foriter: lvalue
       | call
       ;

loop: ';'
    | loopblock
    ;

loopblock: '{' '}'
         | '{' loopstmts '}'
         ;

loopstmts: loopstmt
         | loopstmts loopstmt
         ;

loopstmt: "break"
        | "continue"
        | loopblock
        | stmt
        ;

while: "while" '(' expr ')' loop
     | "do" loopblock "while" '(' expr ')'
     ;

switch: "switch" '(' expr ')' '{' cases '}'
      ;

cases: allcases "default" ':' stmts
     ;

allcases: "case" expr ':' casestmts
        | allcases "case" expr ':' casestmts
        ;

casestmts: casestmt
         | casestmts casestmt
         ;

casestmt: "break"
        | caseblock
        | stmt
        ;

caseblock: '{' '}'
         | '{' casestmts '}'
         ;

Name: long long 2012-01-14 23:41

Another valid program, mandelbrot, gave [or reassured] me some ideas:
* C-compatible ABI (a must)
* importing C headers direcly (it would be good)
* implicit conversion between pointer types / void pointer?
* cpp-like preprocessor, only for #pragmas?
* optional non-qualified imported identifiers if there aren't conflicts?
* OS/arch dependent modules, like the std.sse below?
* modules could specify proper compilation flags, like
        std.sse specifying -mfpmath=sse -msse
        openmp specifying -openmp
        gl specifying -lgl
     which could also ease library dependency chains.

import openmp
import std.sse as sse
import posix
import stdlib

//
// Translated from http://shootout.alioth.debian.org/u32/program.php?test=mandelbrot&lang=gcc&id=4
//

let zero : sse.v2df = { 0.0, 0.0 }
let four : sse.v2df = { 4.0, 4.0 }

var bytes_per_row : int
var inverse_w : double
var inverse_h : double
var N : int

var Crvs : ptr[sse.v2df]
var bitmap : ptr[byte]

def main(args : array[string]) {
    N = atoi(args[1])
   
    bytes_per_row = (N + 7) >> 3

    inverse_w = 2.0 / (bytes_per_row << 3)
    inverse_h = 2.0 / N
   
    if (posix_memalign(@Crvs, sizeof(sse.v2df), sizeof(sse.v2df) * N / 2)) {
        return EXIT_FAILURE
    }

    #omp parallel for
    for (var i = 0; i < N; i += 2) {
        var Crv : sse.v2df = { (i+1.0)*inverse_w-1.5, (i)*inverse_w-1.5 }
        Crvs[i >> 1] = Crv
    }

    bitmap = calloc(bytes_per_row, N)
    if (bitmap == NULL) {
        return EXIT_FAILURE
    }

    #omp parallel for schedule(static,1)
    for (var i = 0; i < N; i++) {
        calc_row(i)
    }

    printf("P4\n%d %d\n", N, N)
    fwrite(bitmap, bytes_per_row, N, stdout)

    free(bitmap)
    free(Crvs)
    return EXIT_SUCCESS
}

def calc_row(y) {
    let row_bitmap = bitmap + (bytes_per_row * y)
    let Civ_init : sse.v2df = { y*inverse_h-1.0, y*inverse_h-1.0 }

    for (var x = 0; x < N; x += 2)
    {
        var Crv = Crvs[x >> 1]
        var Civ = Civ_init
        var Zrv = zero
        var Ziv = zero
        var Trv = zero
        var Tiv = zero
        var i = 50
        var two_pixels : int
        var is_still_bounded : sse.v2df

        do {
            Ziv = (Zrv*Ziv) + (Zrv*Ziv) + Civ
            Zrv = Trv - Tiv + Crv
            Trv = Zrv * Zrv
            Tiv = Ziv * Ziv

            is_still_bounded = sse.cmplepd(Trv + Tiv, four)

            two_pixels = sse.movmskpd(is_still_bounded)
           
            i--
        } while (i > 0 and two_pixels)

        two_pixels <<= 6

        let b : byte = two_pixels >> (x & 7)
        row_bitmap[x >> 3] |= b
    }
}

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List