# AST Module - DSL Compiler for Zanzibar-Graph

This module provides a complete Abstract Syntax Tree (AST) system for parsing and compiling the Evidence DSL into rule configurations that interface with the zanzibar-graph authorization system.

## Overview

The AST module consists of three main components:

1. **Parser** - Converts DSL text into AST nodes
2. **Generator** - Converts AST nodes into rule configurations
3. **Compiler** - Orchestrates the parsing and generation process

## Architecture

```
DSL Text → Parser → AST Nodes → Generator → Rule Configs → setRelationConfig()
```

## Features

- **Complete DSL Support** - Supports all DSL constructs from the specification
- **Modular Design** - Clean separation of concerns with pluggable components
- **Error Handling** - Comprehensive error reporting and validation
- **Program Management** - Support for multiple compiled programs
- **Rule Generation** - Automatic conversion to existing rule system
- **Extensible** - Easy to add new node types and generators

## Quick Start

```javascript
import { DSLCompiler } from './src/ast/index.js';

// Create compiler with arbiter instance
const compiler = new DSLCompiler(arbiter);

// Compile DSL text
const result = compiler.compile(dslText, 'my-program');

if (result.success) {
  console.log(`Generated ${result.generatedCount} rules`);
} else {
  console.error('Compilation errors:', result.errors);
}
```

## Core Components

### 1. AST Nodes (`/nodes/`)

The AST nodes represent the parsed structure of the DSL:

- **BaseNode** - Base class for all AST nodes
- **ProgramNode** - Root node containing all definitions
- **DefinitionNode** - Type definitions with fields and behaviors
- **FactNode** - Fact definitions with parameters and properties
- **EvidenceNode** - Evidence definitions with bodies
- **MeasureNode** - Measure definitions for value collection
- **ExpressionNode** - Expressions, variables, and literals
- **And many more...**

### 2. Parser (`/parser/`)

The DSL parser converts text into AST nodes:

```javascript
import { DSLParser } from './parser/DSLParser.js';

const parser = new DSLParser();
const program = parser.parse(dslText);
```

### 3. Generator (`/generator/`)

The rule generator converts AST nodes into rule configurations:

```javascript
import { RuleGenerator } from './generator/RuleGenerator.js';

const generator = new RuleGenerator(arbiter);
const result = generator.generateRules(program);
```

### 4. Compiler (`DSLCompiler.js`)

The main compiler orchestrates the entire process:

```javascript
import { DSLCompiler } from './DSLCompiler.js';

const compiler = new DSLCompiler(arbiter);
const result = compiler.compile(dslText, 'program-name');
```

## Usage Examples

### Basic Compilation

```javascript
const dsl = `
  definition User {
    role: string
    isActive: boolean
  }
  
  fact hasRole(user: User, role: string) CACHE eager
  
  evidence canRead(user: User, doc: Document) {
    hasRole(user, 'admin')
  }
`;

const result = compiler.compile(dsl, 'auth');
```

### Complex DSL with Defeasible Logic

```javascript
const complexDSL = `
  evidence canAccessCritical(user: User, resource: Resource) {
    // Strict requirement
    ALWAYS user.isActive
    
    // Defeasible access
    WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
    
    // Requirements
    REQUIRES hasClearance(user, resource.level)
    
    // Fusion evidence
    fusion majority {
      user.isTrusted
      user.hasRecentActivity
    }
  }
`;

const result = compiler.compile(complexDSL, 'critical-access');
```

### Multiple Programs

```javascript
const programs = {
  'auth': `
    fact hasRole(user: User, role: string)
    evidence canRead(user: User, doc: Document) {
      hasRole(user, 'admin')
    }
  `,
  'finance': `
    fact hasBalance(user: User, amount: number)
    evidence canWithdraw(user: User, amount: number) {
      hasBalance(user, amount)
    }
  `
};

const result = compiler.compileMultiple(programs);
```

## API Reference

### DSLCompiler

#### Methods

- `compile(dslText, programName)` - Compile DSL text into rules
- `compileMultiple(programs)` - Compile multiple programs
- `validate(dslText)` - Validate DSL without compilation
- `getCompiledProgram(name)` - Get compiled program by name
- `getAllCompiledPrograms()` - Get all compiled programs
- `removeCompiledProgram(name)` - Remove compiled program
- `clearCompiledPrograms()` - Clear all programs
- `getCompilationStats()` - Get compilation statistics

#### Properties

- `arbiter` - The arbiter instance
- `parser` - The DSL parser
- `generator` - The rule generator

### DSLParser

#### Methods

- `parse(dslText)` - Parse DSL text into AST
- `getErrors()` - Get parser errors

### RuleGenerator

#### Methods

- `generateRules(program)` - Generate rules from AST
- `getErrors()` - Get generator errors
- `getGeneratedRules()` - Get generated rules

## Supported DSL Constructs

### Type Definitions

```typescript
definition User {
  role: string
  isActive: boolean
  lastActive: timestamp BEHAVES {
    decaying down hourly
  } CACHE lazy
}
```

### Facts

```typescript
fact hasRole(user: User, role: string) CACHE eager
fact isMember(user: User, group: Group) transitive CACHE lazy
```

### Evidence

```typescript
evidence canRead(user: User, doc: Document) {
  // Direct evidence
  owns(user, doc)
  
  // Pattern matching
  isMember(user, *group) {
    canRead(group, doc)
  } limit 5
  
  // Defeasible logic
  WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
}
```

### Measures

```typescript
measure userBalance(user: User) {
  user.balance
} PROVIDES number

measure userPermissions(user: User) {
  fusion max {
    user.role.permissions
    user.group.permissions
  }
} PROVIDES Permission[]
```

## Error Handling

The compiler provides comprehensive error handling:

```javascript
const result = compiler.compile(dslText);

if (!result.success) {
  console.error('Compilation failed:');
  result.errors.forEach(error => console.error(`  - ${error}`));
}

if (result.warnings.length > 0) {
  console.warn('Warnings:');
  result.warnings.forEach(warning => console.warn(`  - ${warning}`));
}
```

## Testing

Run the test suite:

```javascript
import { runDSLCompilerTests } from './tests/DSLCompiler.test.js';

const testResults = runDSLCompilerTests(arbiter);
console.log('Test Results:', testResults);
```

## Examples

See the examples directory for comprehensive usage examples:

- `examples/DSLExample.js` - Complete usage examples
- `tests/DSLCompiler.test.js` - Test suite

## Integration with Existing System

The AST module integrates seamlessly with the existing zanzibar-graph system:

1. **Parser** converts DSL text to AST nodes
2. **Generator** converts AST nodes to rule configurations
3. **Compiler** applies rules via `arbiter.setRelationConfig()`

The generated rules are compatible with all existing rule types:
- Direct rules
- Computed rules
- Parent rules
- Tuple-to-userset rules
- Similarity rules
- Multi-hop rules
- Logical operators
- Defeasible logic

## Extensibility

The AST system is designed to be extensible:

1. **Add new node types** by extending `BaseNode`
2. **Add new parsers** by extending `DSLParser`
3. **Add new generators** by extending `RuleGenerator`
4. **Add new compilers** by extending `DSLCompiler`

## Performance Considerations

- **Lazy evaluation** - AST nodes are created on demand
- **Efficient parsing** - Token-based parsing with minimal memory usage
- **Rule caching** - Generated rules are cached for reuse
- **Batch processing** - Support for compiling multiple programs at once

## Future Enhancements

- **Incremental compilation** - Only recompile changed parts
- **Parallel processing** - Compile multiple programs in parallel
- **Advanced optimizations** - Rule optimization and simplification
- **IDE support** - Language server protocol support
- **Visualization** - AST visualization tools

## Contributing

When contributing to the AST module:

1. Follow the existing code structure
2. Add comprehensive tests for new features
3. Update documentation
4. Ensure backward compatibility
5. Follow the established patterns

## License

This module is part of the zanzibar-graph project and follows the same license terms.
