List: Statement(s?)
{
    $return = $item[1];
}

Statement: Function | Line | Block
{
    $return = $item[1];
}

Block: Name BArg(?) "{" List "}"
{
    if (@{$item[2]}) {
	$item[2][0]{ "name" } = $item[1];
	$item[2][0]{ "type" } = "block";
	$item[2][0]{ "list" } = $item[4];
	$return = $item[2][0];
    } else {
	$return = { "name" => $item[1],
		    "type" => "block",
		    "count" => 1,
		    "list" => $item[4]  };
    }
}    

Line: Name LArg(?) ";"
{
    if (@{$item[2]}) {
	$item[2][0]{ "name" } = $item[1];
	$return = $item[2][0];
    } else {
	$return = { "name" => $item[1],
		    "type" => "int",
		    "count" => 1,
		    "size" => 32 };
    }
}

Function: Func_Align | Func_Reserve
{
    $return = $item[1];
}



Func_Align: "align" "(" Num ")" ";"
{
    $return = { "name" => "align",
		"type" => "function",
		"count" => 1,
		"args" => [ $item[3] ] };
}

Func_Reserve: "reserve" "(" Num ")" ";"
{
    $return = { "name" => "reserve",
		"type" => "function",
		"count" => 1,
		"args" => [ $item[3] ] };
}

BArg: "(" Cpl ")"
{
    $return = { "count" => $item[2] };
}

LArg: LArgs | BArg
{
    $item[1]{"type"} = "int" unless defined $item[1]{"type"};
    $item[1]{"size"} = 32    unless defined $item[1]{"size"};
    $item[1]{"count"} = 1    unless defined $item[1]{"count"};
    
    $return = $item[1];
}

LArgs: "(" Type "," Cpl LArgsSub(?) ")"
{
    $return = { "type" => $item[2],
		"size" => $item[4],
		"count" => @{$item[5]} ? $item[5][0] : 1 };
}

LArgsSub: "," Cpl
{
    $return = $item[2];
}

Cpl: Num | Ref
{
    $return = $item[1];
}

Type: "int" | "str"
{
    $return = $item[1];
}

Ref: Name ("->" Name)(s?) ("[" Num "]")(?)
{
    $return = [ $item[1], @{$item[2]} ];
}

Name: /[a-zA-Z_][a-zA-Z_0-9]*/
{
    $return = $item[1];
}

Num: /0|[1-9][0-9]*/
{
    $return = $item[1];
}
