(* -----------------------------------------------------
type op = | Add | Sub | Mult | Div | Mod
		  | Equal | Neq | Less | Leq | Greater | Geq
          | LogAnd (* && *)
          | LogOr (* || *)

type uop = Neg | Not
type typ = Int | Bool | Void
type bind = typ * string

type expr = Literal of int 					| BoolLit of bool
			| Id of string 					| Noexpr
			| Binop of expr * op * expr 	| Unop of uop * expr
			| Assign of string * expr 		| Call of string * expr list

type stmt = Block of stmt list 				| Expr of expr
			| If of expr * stmt * stmt
			| For of expr * expr * expr * stmt
			| While of expr * stmt | Return of expr

type func_decl = {
	typ : typ;
	fname : string;
	formals : bind list;
	locals : bind list;
	body : stmt list;
}
type program = bind list * func_decl list

*)

type op =
	| Add | Sub | Mult | Div | Mod
	| Equal | Neq | Less | Leq | Greater | Geq
    | LogAnd (* && *)
	| LogOr (* || *)

type uop = Neg | Not
type bool = True | False

type fun_dt =
	| Basic of (string)
	| List of (string)
	| Dict of (string * string)

type expr =
	| IntLiteral of string
	| FloatLiteral of string
	| StrLiteral of string
	| Null
	| ListLiteral of expr list
	| DictLiteral of (expr * expr) list
	| Boolean of bool
	| Id of string
	| Binop of expr * op * expr
	| Unop of uop * expr
	| Call of string * expr list
	| Access of expr * expr (* for dict and list element access, node.in[node2] *)
	| MemberCall of expr * string * expr list (* expr that evaluates to parent variable, accessed funct, parameters *)
	| Undir of string * string (* id -- id *)
	| Dir of string * string (* id --> id *)
	| UndirVal of string * string * expr (* id, id, weight *)
	| DirVal of string * string * expr (* id, id, weight *)
	| BidirVal of expr * string * string * expr (* weight, id, id, weight *)
	| NoOp of string
	| Noexpr

type stmt =
	| Block of stmt list
	| Expr of expr
	| Vdecl of string * string (* (type, id) *)
	| ListDecl of string * string (* elem_type, id *)
	| DictDecl of string * string * string (* key_type, elem_type, id *)
	| Assign of expr * expr
	| AccessAssign of expr * expr * expr (* a[5] = 10 where first expr is an access expr *)
	| NodeDef of string * expr (* (node id, what goes inside parens) of item *)
	| GraphDef of string * expr list (* id EdgeOp list - in form of undir dir - *)
	| Return of expr
	| If of expr * stmt * stmt
  	| For of string * expr * stmt list (* temp var, iterable var, var decls, stmts *)
  	| While of expr * stmt list (* condition, var decls, stmt list *)
	| Fdecl of func_decl and

	func_decl = {
		rtype: fun_dt;
		fname: string;
		formals : (fun_dt * string) list;
		body: stmt list;
	}

type program = { cmds: stmt list }


