========================================
imports and declarations
========================================

#!/usr/bin/env zuzu

from std/io import Path;
from std/data/json import JSON as Json;
from extras/not_real try import MaybeFeature if enabled;

const String name := "Zuzu";
let { title, "content-type": content_type } := headers;

function greet ( String who ) -> String {
	return "Hello " _ who;
}

class Widget extends Object with Renderable {
	let String label with get, set := "Untitled";

	static method build ( String label ) -> Widget {
		return new Widget( label: label );
	}
}

class Marker;
class Tagged with Taggable;
class Derived extends Base but Printable;

trait Renderable {
	method render () -> String {
		return "";
	}
}

---

(source_file
  (shebang)
  (import_statement
    (module_path)
    (import_list
      (import_specifier
        (type_identifier))))
  (import_statement
    (module_path)
    (import_list
      (import_specifier
        (type_identifier)
        (identifier))))
  (import_statement
    (module_path)
    (import_list
      (import_specifier
        (type_identifier)))
    (identifier))
  (variable_declaration
    (type_expression
      (type_identifier))
    (binding_identifier
      (identifier))
    (string
      (double_quoted_string)))
  (variable_declaration
    (destructuring_pattern
      (destructuring_entry
        (identifier))
      (destructuring_entry
        (string
          (double_quoted_string))
        (identifier)))
    (identifier))
  (function_declaration
    (identifier)
    (parameter_list
      (parameter
        (type_expression
          (type_identifier))
        (binding_identifier
          (identifier))))
    (return_type
      (type_expression
        (type_identifier)))
    (block
      (return_statement
        (binary_expression
          (string
            (double_quoted_string))
          (identifier)))))
  (class_declaration
    (binding_identifier
      (type_identifier))
    (type_expression
      (type_identifier))
    (trait_composition
      (type_expression
        (type_identifier)))
    (class_body
      (field_declaration
        (type_expression
          (type_identifier))
        (identifier)
        (field_accessor_list)
        (string
          (double_quoted_string)))
      (method_declaration
        (identifier)
        (parameter_list
          (parameter
            (type_expression
              (type_identifier))
            (binding_identifier
              (identifier))))
        (return_type
          (type_expression
            (type_identifier)))
        (block
          (return_statement
            (new_expression
              (constructor_target
                (type_expression
                  (type_identifier)))
              (argument_list
                (pair_entry
                  (bare_key
                    (identifier))
                  (identifier)))))))))
  (class_declaration
    (binding_identifier
      (type_identifier)))
  (class_declaration
    (binding_identifier
      (type_identifier))
    (trait_composition
      (type_expression
        (type_identifier))))
  (class_declaration
    (binding_identifier
      (type_identifier))
    (type_expression
      (type_identifier))
    (trait_composition
      (type_expression
        (type_identifier))))
  (trait_declaration
    (binding_identifier
      (type_identifier))
    (trait_body
      (method_declaration
        (identifier)
        (parameter_list)
        (return_type
          (type_expression
            (type_identifier)))
        (block
          (return_statement
            (string
              (double_quoted_string))))))))

========================================
control flow
========================================

if ( ready ) {
	say "ready";
}
else {
	warn "not ready";
}

while ( keep_going ) {
	next;
}

while ( tagged ) {
	obj := obj{value}
}

for ( let item in items ) {
	say item;
}
else {
	say "empty";
}

switch ( status ) {
	case "ok":
		say "ok";
	case ~ /fail/:
		throw status;
	default:
		die "unknown";
}

try {
	do_work();
}
catch ( Exception ex ) {
	warn ex;
}

---

(source_file
  (if_statement
    (parenthesized_expression
      (identifier))
    (block
      (builtin_statement
        (string
          (double_quoted_string))))
    (block
      (builtin_statement
        (string
          (double_quoted_string)))))
  (while_statement
    (parenthesized_expression
      (identifier))
    (block
      (loop_control_statement)))
  (while_statement
    (parenthesized_expression
      (identifier))
    (block
      (assignment_statement
        (assignment_expression
          (identifier)
          (assignment_operator)
          (dict_access_expression
            (identifier)
            (identifier))))))
  (for_statement
    (identifier)
    (identifier)
    (block
      (builtin_statement
        (identifier)))
    (block
      (builtin_statement
        (string
          (double_quoted_string)))))
  (switch_statement
    (switch_header
      (identifier))
    (case_clause
      (case_value
        (string
          (double_quoted_string)))
      (builtin_statement
        (string
          (double_quoted_string))))
    (case_clause
      (case_operator_value
        (operator_name)
        (regexp))
      (throw_statement
        (identifier)))
    (default_clause
      (throw_statement
        (string
          (double_quoted_string)))))
  (try_statement
    (block
      (expression_statement
        (call_expression
          (identifier)
          (argument_list))))
    (catch_clause
      (type_expression
        (type_identifier))
      (identifier)
      (block
        (builtin_statement
          (identifier))))))
