---------------------------------------------------------------- Source/circuit/Main.java ---------------------------------------------------------------- package circuit; import java.io.*; import java_cup.runtime.*; import node.*; import node.stmtNode.*; import text.*; import grammar.*; import runEnv.*; public class Main { public static boolean debug = false; public static boolean expand = false; public static boolean print = false; public static void main( String[] argv ) { String dirName = null; try { for ( int i = 0; i < argv.length; i++ ) { if ( argv[ i ].equals( "-debug" ) ) { debug = true; } if ( argv[ i ].equals( "-expand" ) ) { expand = true; } else if ( argv[ i ].equals( "-print" ) ) { print = true; } else if ( argv[ i ].equals( "-dir" ) ) { i++; if ( i >= argv.length ) throw new Error( "Missing directory name" ); dirName = argv[ i ]; } else { throw new Error( "Usage: java Main [-debug] -dir directory" ); } } if ( dirName == null ) throw new Error( "Directory not specified" ); Print.setError( new File( dirName, "program.err" ) ); Print.setReprint( new File( dirName, "program.print" ) ); Print.setInterp( new File( dirName, "program.out" ) ); parser libraryParser = new parser( new File( "LIBRARY", "globalLibrary.in" ) ); DeclStmtListNode globalLibrary = ( DeclStmtListNode ) libraryParser.parse().value; parser programParser = new parser( new File( dirName, "program.in" ) ); DeclStmtListNode declStmtList = ( DeclStmtListNode ) programParser.parse().value; ProgramNode program = new ProgramNode( globalLibrary, declStmtList ); Print.error().println( "Reprinting ... " ); Print.reprint().print( program ); if ( print ) System.exit( 0 ); Print.error().println( "Evaluate ... " ); try { program.eval(); } catch ( Error exception ) { Print.error().println( "User Error " + exception.getMessage() ); Print.error().printStackTrace( exception ); } } catch ( Throwable exception ) { exception.printStackTrace(); Print.error().println( "Exception in Main " + exception ); Print.error().printStackTrace( exception ); System.exit( -1 ); } } } ---------------------------------------------------------------- Source/grammar/Yylex.jflex ---------------------------------------------------------------- package grammar; import text.*; import java_cup.runtime.*; import java.io.*; import java.util.*; %% %public %type Symbol %char %{ private int lineNumber = 1; public int lineNumber() { return lineNumber; } public Symbol token( int tokenType, String text ) { Print.error().debugln( "Obtain token " + sym.terminal_name( tokenType ) + " \"" + text + "\"" ); return new Symbol( tokenType, yychar, yychar + yytext().length(), text ); } public Symbol token( int tokenType ) { return token( tokenType, yytext() ); } %} %init{ yybegin( NORMALSTATE ); %init} decConst = [0-9]+ ident = [A-Za-z][A-Za-z0-9]* space = [\ \t] newline = \r|\n|\r\n octEsc = \\[0-3][0-7][0-7] hexEsc = \\[xX][0-9a-fA-F][0-9a-fA-F] charEsc = \\[ntbrfva\\\'\"] schar = [^\'\"\\\r\n]|{octEsc}|{hexEsc}|{charEsc} strConst = \"{schar}*\" %state NORMALSTATE, COMMENT1STATE, COMMENT2STATE, LEXERRORSTATE %% { {newline} { lineNumber++; } {space} { } "(" { return token( sym.LEFT ); } ")" { return token( sym.RIGHT ); } "[" { return token( sym.LEFTSQ ); } "]" { return token( sym.RIGHTSQ ); } "{" { return token( sym.LEFTBRACE ); } "}" { return token( sym.RIGHTBRACE ); } ";" { return token( sym.SEMICOLON ); } "," { return token( sym.COMMA ); } "." { return token( sym.DOT ); } "@" { return token( sym.AT ); } "=" { return token( sym.ASSIGN ); } "?" { return token( sym.QUEST ); } ":" { return token( sym.COLON ); } "||" { return token( sym.OR ); } "&&" { return token( sym.AND ); } "<" { return token( sym.LT ); } ">" { return token( sym.GT ); } "<=" { return token( sym.LE ); } ">=" { return token( sym.GE ); } "==" { return token( sym.EQ ); } "!=" { return token( sym.NE ); } "<<" { return token( sym.LEFTSHIFT ); } ">>" { return token( sym.RIGHTSHIFT ); } "+" { return token( sym.PLUS ); } "-" { return token( sym.MINUS ); } "&" { return token( sym.AMPERSAND ); } "*" { return token( sym.TIMES ); } "/" { return token( sym.DIVIDE ); } "%" { return token( sym.MOD ); } "!" { return token( sym.NOT ); } include { return token( sym.INCLUDE ); } define { return token( sym.DEFINE ); } path { return token( sym.PATH ); } in { return token( sym.IN ); } out { return token( sym.OUT ); } component { return token( sym.COMPONENT ); } begin { return token( sym.BEGIN ); } end { return token( sym.END ); } if { return token( sym.IF ); } then { return token( sym.THEN ); } else { return token( sym.ELSE ); } elif { return token( sym.ELIF ); } for { return token( sym.FOR ); } from { return token( sym.FROM ); } upto { return token( sym.UPTO ); } do { return token( sym.DO ); } true { return token( sym.TRUE ); } false { return token( sym.FALSE ); } {decConst} { return token( sym.DECLITERAL ); } {strConst} { return token( sym.STRINGLITERAL ); } {ident} { return token( sym.IDENT ); } "//" { yybegin( COMMENT1STATE ); } "/*" { yybegin( COMMENT2STATE ); } . { yybegin( LEXERRORSTATE ); return token( sym.error ); } } { {newline} { lineNumber++; yybegin( NORMALSTATE ); return token( sym.error ); } . { } } { {newline} { lineNumber++; yybegin( NORMALSTATE ); } . { } } { "*/" { yybegin( NORMALSTATE ); } {newline} { lineNumber++; } . { } } <> { return token( sym.EOF ); } ---------------------------------------------------------------- Source/grammar/parser.cup ---------------------------------------------------------------- package grammar; import java.io.*; import java.util.*; import java_cup.runtime.*; import node.*; import node.declNode.*; import node.declNode.componentDeclNode.*; import node.declNode.pathDefnNode.*; import node.declNode.valueDefnNode.*; import node.stmtNode.*; import node.stmtNode.forStmtNode.*; import node.stmtNode.ifStmtNode.*; // import node.stmtNode.ifStmtNode.elseOptNode.*; import node.stmtNode.invocationStmtNode.*; import node.stmtNode.includeStmtNode.*; import node.exprNode.*; import node.exprNode.binaryNode.*; import node.exprNode.binaryNode.arithNode.*; import node.exprNode.binaryNode.stringNode.*; import node.exprNode.binaryNode.relationNode.*; import node.exprNode.binaryNode.boolNode.*; import node.exprNode.prefixNode.*; import node.exprNode.valueNode.*; import node.pathNode.*; import node.pathNode.pathNameNode.*; import text.*; parser code {: private Yylex lexer; private File inputFile; public File inputFile() { return inputFile; }; public int lineNumber() { return lexer.lineNumber(); } public parser( File inputFile ) { this(); this.inputFile = inputFile; try { lexer = new Yylex( new FileReader( inputFile ) ); } catch ( IOException exception ) { throw new Error( "Unable to open file \"" + inputFile + "\"" ); } } public String terminal_name( int id ) { return sym.terminal_name( id ); } public String non_terminal_name( int id ) { return sym.non_terminal_name( id ); } public String rule_name( int id ) { return sym.rule_name( id ); } public void report_error( String message, Object info ) { Print.error().println( inputFile + " ( " + lexer.lineNumber() + " ): " + message ); try { if ( info instanceof Symbol ) { Symbol symbol = ( Symbol ) info; printText( symbol.left, symbol.right ); } } catch ( IOException e ) { } } private void printText( int left, int right ) throws IOException { Reader sourceReader = new FileReader( inputFile ); int veryLeft = Math.max( left - 50, 0 ), veryRight = Math.min( right + 20, ( int ) inputFile.length() ); char[] text = new char[ veryRight - veryLeft ]; char[] underline = new char[ veryRight - veryLeft ]; sourceReader.skip( veryLeft ); sourceReader.read( text ); for ( int i = 0; i < text.length; i++ ) { if ( text[ i ] < ' ' ) { text[ i ] = '|'; underline[ i ] = '|'; } else underline[ i ] = ' '; if ( left <= veryLeft + i && veryLeft + i < right ) underline[ i ] = '^'; } printLine( text ); printLine( underline ); } private static void printLine( char[] text ) { for ( int i = 0; i < text.length; i++ ) Print.error().print( text[ i ] ); Print.error().println(); } public void syntax_error( Symbol currToken ) { report_error( "Syntax Error", currToken ); } :}; scan with {: return lexer.yylex(); :}; /****************************************************************** Terminal Symbols ******************************************************************/ terminal INCLUDE, DEFINE, PATH, IN, OUT, COMPONENT, BEGIN, END, IF, THEN, ELSE, ELIF, FOR, FROM, UPTO, DO, LEFT, RIGHT, LEFTSQ, RIGHTSQ, AT, LEFTBRACE, RIGHTBRACE, SEMICOLON, COMMA, DOT, ASSIGN, QUEST, COLON, OR, AND, LT, GT, LE, GE, EQ, NE, LEFTSHIFT, RIGHTSHIFT, PLUS, MINUS, AMPERSAND, TIMES, DIVIDE, MOD, NOT, TRUE, FALSE; terminal String DECLITERAL; terminal String STRINGLITERAL; terminal String IDENT; /****************************************************************** Nonterminal Symbols ******************************************************************/ nonterminal DeclStmtListNode GlobalDeclStmtList, LocalDeclStmtList; nonterminal DeclStmtNode GlobalDeclStmt, LocalDeclStmt, ComponentDecl, ValueDecl, PathDecl; nonterminal ValueDefnListNode InitValueDefnList, ValueParamDecl, ValueParamDefnList; nonterminal ValueDefnNode InitValueDefn, ValueParamDefn; nonterminal PathDefnListNode InputParamDecl, OutputParamDecl, PathDefnList; nonterminal PathDefnNode PathDefn; nonterminal BodyNode Body; nonterminal StmtNode IfStmt, ForStmt, InvocationStmt, IncludeStmt; nonterminal InvocListNode InvocList; nonterminal InvocNode Invoc; nonterminal ElseOptNode ElseOpt; nonterminal PathArrayListNode InputParams, OutputParams, PathArrayList; nonterminal PathArrayNode PathArray; nonterminal PathNameListNode PathNameList; nonterminal PathNameNode PathName; nonterminal ExprListNode ValueParams, ExprList; nonterminal ExprNode Expr, CondExpr, OrExpr, AndExpr, RelExpr, ShiftExpr, AddExpr, MulExpr, PrefixExpr, Primary, LiteralValue; /****************************************************************** The Grammar ******************************************************************/ start with GlobalDeclStmtList; /****************************************************************** Statements ******************************************************************/ GlobalDeclStmtList::= /* Empty */ {: RESULT = new DeclStmtListNode(); :} | GlobalDeclStmtList:declStmtList GlobalDeclStmt:declStmt {: declStmtList.addElement( declStmt ); RESULT = declStmtList; :} ; GlobalDeclStmt::= ComponentDecl:decl {: RESULT = decl; :} | IncludeStmt:stmt {: RESULT = stmt; :} | LocalDeclStmt:declStmt {: RESULT = declStmt; :} ; LocalDeclStmtList::= /* Empty */ {: RESULT = new DeclStmtListNode(); :} | LocalDeclStmtList:declStmtList LocalDeclStmt:declStmt {: declStmtList.addElement( declStmt ); RESULT = declStmtList; :} ; LocalDeclStmt::= ValueDecl:decl {: RESULT = decl; :} | PathDecl:decl {: RESULT = decl; :} | IfStmt:stmt {: RESULT = stmt; :} | ForStmt:stmt {: RESULT = stmt; :} | InvocationStmt:stmt {: RESULT = stmt; :} ; /****************************************************************** Init Value Declarations ******************************************************************/ /****************************************************************** Value Parameter Declarations ******************************************************************/ /****************************************************************** Path Declarations ******************************************************************/ /****************************************************************** Path Parameter Declarations ******************************************************************/ /****************************************************************** Component Declarations ******************************************************************/ /****************************************************************** Include Statements ******************************************************************/ IncludeStmt::= INCLUDE STRINGLITERAL:value SEMICOLON {: try { String includeFileName = Convert.parseString( value.substring( 1, value.length() - 1 ) ); File includeFile = new File( includeFileName ); parser p = new parser( includeFile ); DeclStmtListNode includeProgram = ( DeclStmtListNode ) ( p.parse().value ); RESULT = new IncludeStmtNode( includeFileName, includeProgram ); } catch ( IOException error ) { Print.error().println( "Can't open included file \"" + parser.inputFile() ); RESULT = new ErrorStmtNode(); } :} ; /****************************************************************** Control Statements ******************************************************************/ /****************************************************************** Invocations ******************************************************************/ /****************************************************************** Paths ******************************************************************/ PathArrayList::= PathArray:pathArray {: RESULT = new PathArrayListNode( pathArray ); :} | PathArrayList:pathArrayList COMMA PathArray:pathArray {: pathArrayList.addElement( pathArray ); RESULT = pathArrayList; :} ; PathArray::= PathNameList:pathNameList {: RESULT = new PathArrayNode( pathNameList ); :} ; PathName::= IDENT:ident {: RESULT = new SimplePathNameNode( ident ); :} ; /****************************************************************** Expressions ******************************************************************/ ExprList::= Expr:expr {: RESULT = new ExprListNode( expr ); :} | ExprList:exprList COMMA Expr:expr {: exprList.addElement( expr ); RESULT = exprList; :} ; Expr::= CondExpr:expr {: RESULT = expr; :} ; CondExpr::= OrExpr:cond QUEST Expr:expr1 COLON Expr:expr2 {: RESULT = new CondNode( cond, expr1, expr2 ); :} | OrExpr:expr {: RESULT = expr; :} ; OrExpr::= OrExpr:expr1 OR AndExpr:expr2 {: RESULT = new OrNode( expr1, expr2 ); :} | AndExpr:expr {: RESULT = expr; :} ; AndExpr::= AndExpr:expr1 AND RelExpr:expr2 {: RESULT = new AndNode( expr1, expr2 ); :} | RelExpr:expr {: RESULT = expr; :} ; RelExpr::= ShiftExpr:expr1 LT ShiftExpr:expr2 {: RESULT = new LessThanNode( expr1, expr2 ); :} | ShiftExpr:expr1 GT ShiftExpr:expr2 {: RESULT = new GreaterThanNode( expr1, expr2 ); :} | ShiftExpr:expr1 LE ShiftExpr:expr2 {: RESULT = new LessEqualNode( expr1, expr2 ); :} | ShiftExpr:expr1 GE ShiftExpr:expr2 {: RESULT = new GreaterEqualNode( expr1, expr2 ); :} | ShiftExpr:expr1 EQ ShiftExpr:expr2 {: RESULT = new EqualNode( expr1, expr2 ); :} | ShiftExpr:expr1 NE ShiftExpr:expr2 {: RESULT = new NotEqualNode( expr1, expr2 ); :} | ShiftExpr:expr {: RESULT = expr; :} ; ShiftExpr::= ShiftExpr:expr1 LEFTSHIFT AddExpr:expr2 {: RESULT = new LeftShiftNode( expr1, expr2 ); :} | ShiftExpr:expr1 RIGHTSHIFT AddExpr:expr2 {: RESULT = new RightShiftNode( expr1, expr2 ); :} | AddExpr:expr {: RESULT = expr; :} ; AddExpr::= AddExpr:expr1 PLUS MulExpr:expr2 {: RESULT = new PlusNode( expr1, expr2 ); :} | AddExpr:expr1 MINUS MulExpr:expr2 {: RESULT = new MinusNode( expr1, expr2 ); :} | AddExpr:expr1 AMPERSAND MulExpr:expr2 {: RESULT = new ConcatStringNode( expr1, expr2 ); :} | MulExpr:expr {: RESULT = expr; :} ; MulExpr::= MulExpr:expr1 TIMES PrefixExpr:expr2 {: RESULT = new TimesNode( expr1, expr2 ); :} | MulExpr:expr1 DIVIDE PrefixExpr:expr2 {: RESULT = new DivideNode( expr1, expr2 ); :} | MulExpr:expr1 MOD PrefixExpr:expr2 {: RESULT = new ModNode( expr1, expr2 ); :} | PrefixExpr:expr {: RESULT = expr; :} ; PrefixExpr::= MINUS PrefixExpr:expr {: RESULT = new NegateNode( expr ); :} | NOT PrefixExpr:expr {: RESULT = new NotNode( expr ); :} | Primary:expr {: RESULT = expr; :} ; Primary::= LEFT Expr:expr RIGHT {: RESULT = expr; :} | IDENT:ident {: RESULT = new NameNode( ident ); :} | LiteralValue:value {: RESULT = value; :} ; LiteralValue::= DECLITERAL:value {: RESULT = new IntValueNode( Integer.valueOf( value, 10 ).intValue() ); :} | TRUE {: RESULT = new BoolValueNode( true ); :} | FALSE {: RESULT = new BoolValueNode( false ); :} | STRINGLITERAL:value {: RESULT = new StringValueNode( Convert.parseString( value.substring( 1, value.length() - 1 ) ) ); :} ; ---------------------------------------------------------------- Source/node/Node.java ---------------------------------------------------------------- package node; import runEnv.*; public abstract class Node { public abstract String toString(); } ---------------------------------------------------------------- Source/node/ListNode.java ---------------------------------------------------------------- package node; import node.*; import runEnv.*; import text.*; import java.util.*; public class ListNode< ElementType > extends Node { private Vector< ElementType > list = new Vector< ElementType >(); private String separator; public ListNode( String separator ) { this.separator = separator; } public int size() { return list.size(); } public ElementType elementAt( int i ) { return ( ElementType ) list.elementAt( i ); } public void addElement( ElementType element ) { list.addElement( element ); } public String toString() { String result = ""; for ( int i = 0; i < size(); i++ ) { if ( i > 0 ) result += separator; ElementType element = elementAt( i ); result += element; } return result; } } ---------------------------------------------------------------- Source/node/exprNode/valueNode/IntValueNode.java ---------------------------------------------------------------- package node.exprNode.valueNode; import node.*; import node.exprNode.*; import runEnv.*; import runEnv.basicValue.*; public class IntValueNode extends ValueNode { private int value; public IntValueNode( int value ) { this.value = value; } public String toString() { return "" + value; } public RunValue eval( RunEnv runEnv ) { return new IntValue( value ); } } ---------------------------------------------------------------- Source/node/declNode/ValueDeclNode.java ---------------------------------------------------------------- package node.declNode; import node.declNode.valueDefnNode.*; import runEnv.*; public class ValueDeclNode extends DeclNode { } ---------------------------------------------------------------- Source/node/declNode/valueDefnNode/ValueDefnListNode.java ---------------------------------------------------------------- package node.declNode.valueDefnNode; import node.*; import runEnv.*; public class ValueDefnListNode extends ListNode< ValueDefnNode > { public ValueDefnListNode() { super( ", " ); } public ValueDefnListNode( ValueDefnNode node ) { this(); addElement( node ); } public void eval( int kind, RunEnv runEnv, RunValue[] value ) { throw new Error( "ValueDefnListNode Unimplemented" ); } } ---------------------------------------------------------------- Source/node/declNode/valueDefnNode/ValueDefnNode.java ---------------------------------------------------------------- package node.declNode.valueDefnNode; import node.*; import node.exprNode.*; import runEnv.*; public abstract class ValueDefnNode extends Node { } ---------------------------------------------------------------- Source/node/declNode/valueDefnNode/InitValueDefnNode.java ---------------------------------------------------------------- package node.declNode.valueDefnNode; import node.*; import node.exprNode.*; import runEnv.*; public class InitValueDefnNode extends ValueDefnNode { } ---------------------------------------------------------------- Source/node/declNode/valueDefnNode/ValueParamDefnNode.java ---------------------------------------------------------------- package node.declNode.valueDefnNode; import node.*; import runEnv.*; public class ValueParamDefnNode extends ValueDefnNode { } ---------------------------------------------------------------- Source/node/declNode/PathDeclNode.java ---------------------------------------------------------------- package node.declNode; import node.declNode.pathDefnNode.*; import runEnv.*; public class PathDeclNode extends DeclNode { private PathDefnListNode pathDefnList; public PathDeclNode( PathDefnListNode pathDefnList ) { this.pathDefnList = pathDefnList; } public String toString() { return "path " + pathDefnList + ";"; } public void eval( RunEnv runEnv ) { pathDefnList.eval( RunDecl.PATH, runEnv, new PathArrayValue[ pathDefnList.size() ] ); } } ---------------------------------------------------------------- Source/node/declNode/pathDefnNode/PathDefnListNode.java ---------------------------------------------------------------- package node.declNode.pathDefnNode; import node.*; import runEnv.*; public class PathDefnListNode extends ListNode< PathDefnNode > { public PathDefnListNode() { super( ", " ); } public PathDefnListNode( PathDefnNode node ) { this(); addElement( node ); } public void eval( int kind, RunEnv runEnv, PathArrayValue[] value ) { if ( value.length != size() ) throw new Error( "Incorrect number of path parameters" ); for ( int i = 0; i < size(); i++ ) { PathDefnNode element = elementAt( i ); value[ i ] = element.eval( kind, runEnv, value[ i ] ); } } } ---------------------------------------------------------------- Source/node/declNode/pathDefnNode/PathDefnNode.java ---------------------------------------------------------------- package node.declNode.pathDefnNode; import node.*; import runEnv.*; public abstract class PathDefnNode extends Node { protected String ident; public String ident() { return ident; } public abstract PathArrayValue eval( int kind, RunEnv runEnv, PathArrayValue value ); } ---------------------------------------------------------------- Source/node/declNode/pathDefnNode/SimplePathDefnNode.java ---------------------------------------------------------------- package node.declNode.pathDefnNode; import runEnv.*; public class SimplePathDefnNode extends PathDefnNode { public SimplePathDefnNode( String ident ) { this.ident = ident; } public String toString() { return ident; } public PathArrayValue eval( int kind, RunEnv runEnv, PathArrayValue value ) { if ( value == null ) value = new PathArrayValue( 1 ); if ( value.size() != 1 ) throw new Error( "Incompatible parameter " + value + " for " + this ); runEnv.declare( kind, ident, value ); return value; } } ---------------------------------------------------------------- Source/node/declNode/pathDefnNode/ArrayPathDefnNode.java ---------------------------------------------------------------- package node.declNode.pathDefnNode; import node.exprNode.*; import runEnv.*; public class ArrayPathDefnNode extends PathDefnNode { private ExprNode size; public ArrayPathDefnNode( String ident, ExprNode size ) { this.ident = ident; this.size = size; } public String toString() { return ident + "[ " + size + " ]"; } public PathArrayValue eval( int kind, RunEnv runEnv, PathArrayValue value ) { int sizeValue = size.eval( runEnv ).intValue(); if ( value == null ) value = new PathArrayValue( sizeValue ); if ( value.size() != sizeValue ) throw new Error( "Incompatible parameter " + value + " for " + ident + "[ " + sizeValue + " ]" ); runEnv.declare( kind, ident, value ); return value; } } ---------------------------------------------------------------- Source/node/declNode/componentDeclNode/ComponentDeclNode.java ---------------------------------------------------------------- package node.declNode.componentDeclNode; import node.declNode.*; import node.declNode.pathDefnNode.*; import node.declNode.valueDefnNode.*; import runEnv.*; public class ComponentDeclNode extends DeclNode { private PathDefnListNode inputParamDecl; private String ident; private ValueDefnListNode paramDecl; private PathDefnListNode outputParamDecl; private BodyNode body; public PathDefnListNode inputParamDecl() { return inputParamDecl; } public String ident() { return ident; } public ValueDefnListNode paramDecl() { return paramDecl; } public PathDefnListNode outputParamDecl() { return outputParamDecl; } public ComponentDeclNode( PathDefnListNode inputParamDecl, String ident, ValueDefnListNode paramDecl, PathDefnListNode outputParamDecl, BodyNode body ) { this.inputParamDecl = inputParamDecl; this.ident = ident; this.paramDecl = paramDecl; this.outputParamDecl = outputParamDecl; this.body = body; } public String toString() { throw new Error( "ComponentDeclNode.toString() Unimplemented" ); } public void eval( RunEnv runEnv ) { runEnv.declare( RunDecl.COMPONENT, ident, new ComponentValue( this, runEnv ) ); } public void invoke( RunEnv declEnv, PathArrayValue[] inputParamValues, RunValue[] paramValues, PathArrayValue[] outputParamValues ) { RunEnv localEnv = new RunEnv( ident, declEnv ); paramDecl.eval( RunDecl.VALUEPARAM, localEnv, paramValues ); inputParamDecl.eval( RunDecl.INPUTPARAM, localEnv, inputParamValues ); outputParamDecl.eval( RunDecl.OUTPUTPARAM, localEnv, outputParamValues ); body.eval( localEnv ); } } ---------------------------------------------------------------- Source/node/declNode/componentDeclNode/BodyNode.java ---------------------------------------------------------------- package node.declNode.componentDeclNode; import node.*; import runEnv.*; public abstract class BodyNode extends Node { public abstract void eval( RunEnv runEnv ); } ---------------------------------------------------------------- Source/node/declNode/componentDeclNode/EmptyBodyNode.java ---------------------------------------------------------------- package node.declNode.componentDeclNode; import runEnv.*; import builtin.*; import text.*; public class EmptyBodyNode extends BodyNode { public EmptyBodyNode() { } public String toString() { return ";"; } public void eval( RunEnv runEnv ) { Print.interp().println( runEnv ); String name = runEnv.name(); Component component; if ( name.equals( "literal" ) ) component = new LiteralComponent( runEnv ); else if ( name.equals( "counter" ) ) component = new CounterComponent( runEnv ); else if ( name.equals( "input" ) ) component = new InputComponent( runEnv ); else if ( name.equals( "output" ) ) component = new OutputComponent( runEnv ); else if ( name.equals( "memory" ) ) component = new MemoryComponent( runEnv ); else if ( name.equals( "or" ) ) component = new OrComponent( runEnv ); else if ( name.equals( "and" ) ) component = new AndComponent( runEnv ); else if ( name.equals( "xor" ) ) component = new XorComponent( runEnv ); else if ( name.equals( "not" ) ) component = new NotComponent( runEnv ); else if ( name.equals( "join" ) ) component = new JoinComponent( runEnv ); else if ( name.equals( "select" ) ) component = new SelectComponent( runEnv ); else if ( name.equals( "decode" ) ) component = new DecodeComponent( runEnv ); else throw new Error( "Unknown built-in component " + name ); component.start(); } } ---------------------------------------------------------------- Source/node/declNode/componentDeclNode/NonEmptyBodyNode.java ---------------------------------------------------------------- package node.declNode.componentDeclNode; import node.*; import runEnv.*; public class NonEmptyBodyNode extends BodyNode { private DeclStmtListNode body; public NonEmptyBodyNode( DeclStmtListNode body ) { this.body = body; } public String toString() { return "%nbegin%+%n" + body + "%-%nend"; } public void eval( RunEnv runEnv ) { body.eval( runEnv ); } } ---------------------------------------------------------------- Source/node/stmtNode/forStmtNode/ForStmtNode.java ---------------------------------------------------------------- package node.stmtNode.forStmtNode; import node.*; import node.stmtNode.*; import node.exprNode.*; import runEnv.*; import runEnv.basicValue.*; public class ForStmtNode extends StmtNode { } ---------------------------------------------------------------- Source/node/stmtNode/ifStmtNode/IfStmtNode.java ---------------------------------------------------------------- package node.stmtNode.ifStmtNode; import node.*; import node.stmtNode.*; import node.stmtNode.ifStmtNode.elseOptNode.*; import node.exprNode.*; import runEnv.*; public class IfStmtNode extends StmtNode { } ---------------------------------------------------------------- Source/node/stmtNode/invocationStmtNode/InvocationStmtNode.java ---------------------------------------------------------------- package node.stmtNode.invocationStmtNode; import node.stmtNode.*; import node.exprNode.*; import node.pathNode.*; import node.declNode.componentDeclNode.*; import node.declNode.pathDefnNode.*; import node.declNode.valueDefnNode.*; import runEnv.*; public class InvocationStmtNode extends StmtNode { private PathArrayListNode inputParams; private InvocNode invoc; private PathArrayListNode outputParams; public InvocationStmtNode( PathArrayListNode inputParams, InvocNode invoc, PathArrayListNode outputParams ) { this.inputParams = inputParams; this.invoc = invoc; this.outputParams = outputParams; } public String toString() { throw new Error( "InvocationStmtNode.toString() Unimplemented" ); } public void eval( RunEnv runEnv ) { PathArrayValue[] inputParamValues = inputParams.eval( runEnv ); PathArrayValue[] outputParamValues = outputParams.eval( runEnv ); invoc.eval( runEnv, inputParamValues, outputParamValues ); } } ---------------------------------------------------------------- Source/node/stmtNode/invocationStmtNode/InvocNode.java ---------------------------------------------------------------- package node.stmtNode.invocationStmtNode; import node.*; import node.exprNode.*; import node.pathNode.*; import runEnv.*; public class InvocNode extends Node { private String ident; private ExprListNode valueParams; public String ident() { return ident; } public ExprListNode valueParams() { return valueParams; } public InvocNode( String ident, ExprListNode valueParams ) { this.ident = ident; this.valueParams = valueParams; } public String toString() { String valueParamsText = ""; if ( valueParams.size() != 0 ) valueParamsText = "( " + valueParams + " )"; return ident + valueParamsText; } public void eval( RunEnv runEnv, PathArrayValue[] inputParamValues, PathArrayValue[] outputParamValues ) { ComponentValue componentValue = runEnv.getValue( ident ).componentValue(); RunValue[] paramValues = valueParams.eval( runEnv ); componentValue.eval( inputParamValues, paramValues, outputParamValues ); } } ---------------------------------------------------------------- Source/node/pathNode/PathArrayListNode.java ---------------------------------------------------------------- package node.pathNode; import node.*; import runEnv.*; public class PathArrayListNode extends ListNode< PathArrayNode > { public PathArrayListNode() { super( ", " ); } public PathArrayListNode( PathArrayNode node ) { this(); addElement( node ); } public PathArrayValue[] eval( RunEnv runEnv ) { PathArrayValue[] result = new PathArrayValue[ size() ]; for ( int i = 0; i < size(); i++ ) { PathArrayNode element = elementAt( i ); result[ i ] = element.eval( runEnv ); } return result; } } ---------------------------------------------------------------- Source/node/pathNode/PathArrayNode.java ---------------------------------------------------------------- package node.pathNode; import node.*; import node.pathNode.pathNameNode.*; import runEnv.*; public class PathArrayNode extends Node { private PathNameListNode pathNameList; public PathArrayNode( PathNameListNode pathNameList ) { this.pathNameList = pathNameList; } public String toString() { return "" + pathNameList; } public PathArrayValue eval( RunEnv runEnv ) { return new PathArrayValue( pathNameList.eval( runEnv ) ); } } ---------------------------------------------------------------- Source/node/pathNode/pathNameNode/PathNameListNode.java ---------------------------------------------------------------- package node.pathNode.pathNameNode; import node.*; import runEnv.*; public class PathNameListNode extends ListNode< PathNameNode > { public PathNameListNode() { super( " " ); } public PathNameListNode( PathNameNode node ) { this(); addElement( node ); } public PathArrayValue[] eval( RunEnv runEnv ) { throw new Error( "PathNameListNode Unimplemented" ); } } ---------------------------------------------------------------- Source/node/pathNode/pathNameNode/PathNameNode.java ---------------------------------------------------------------- package node.pathNode.pathNameNode; import node.*; import runEnv.*; public abstract class PathNameNode extends Node { public abstract PathArrayValue eval( RunEnv runEnv ); } ---------------------------------------------------------------- Source/node/pathNode/pathNameNode/SimplePathNameNode.java ---------------------------------------------------------------- package node.pathNode.pathNameNode; import runEnv.*; public class SimplePathNameNode extends PathNameNode { private String ident; public SimplePathNameNode( String ident ) { this.ident = ident; } public String toString() { return ident; } public PathArrayValue eval( RunEnv runEnv ) { return runEnv.getValue( ident ).pathArrayValue(); } } ---------------------------------------------------------------- Source/node/pathNode/pathNameNode/IndexPathNameNode.java ---------------------------------------------------------------- package node.pathNode.pathNameNode; import node.exprNode.*; import runEnv.*; public class IndexPathNameNode extends PathNameNode { } ---------------------------------------------------------------- Source/node/pathNode/pathNameNode/SubArrayPathNameNode.java ---------------------------------------------------------------- package node.pathNode.pathNameNode; import node.exprNode.*; import runEnv.*; public class SubArrayPathNameNode extends PathNameNode { } ---------------------------------------------------------------- Source/runEnv/RunValue.java ---------------------------------------------------------------- package runEnv; import runEnv.basicValue.*; import java.util.*; public abstract class RunValue { /* Represents a run time value */ public boolean boolValue() { throw new Error( "Can't cast runtime value " + this + " to bool" ); } public int intValue() { throw new Error( "Can't cast runtime value " + this + " to int" ); } public String stringValue() { throw new Error( "Can't cast runtime value " + this + " to string" ); } public PathValue pathValue() { throw new Error( "Can't cast runtime " + this + " to path" ); } public PathArrayValue pathArrayValue() { throw new Error( "Can't cast runtime " + this + " to path array" ); } public ComponentValue componentValue() { throw new Error( "Can't cast runtime " + this + " to component" ); } public boolean isBool() { return false; } public boolean isInt() { return false; } public boolean isString() { return false; } public boolean isPathArray() { return false; } public boolean isComponent() { return false; } public abstract String toString(); public abstract boolean equals( Object value ); } ---------------------------------------------------------------- Source/runEnv/basicValue/BasicValue.java ---------------------------------------------------------------- package runEnv.basicValue; import runEnv.*; public abstract class BasicValue extends RunValue { } ---------------------------------------------------------------- Source/runEnv/basicValue/IntValue.java ---------------------------------------------------------------- package runEnv.basicValue; import runEnv.*; public class IntValue extends BasicValue { private int value; public IntValue( int value ) { this.value = value; } public int intValue() { return value; } public String stringValue() { return "" + value; } public boolean isInt() { return true; } public boolean equals( Object other ) { if ( other == null ) return false; if ( ! ( other instanceof RunValue ) ) return false; RunValue runValue = ( RunValue ) other; if ( ! ( runValue instanceof IntValue ) ) return false; IntValue otherIntValue = ( IntValue ) runValue; return value == otherIntValue.intValue(); } public String toString() { return Integer.toString( value, 16 ); } } ---------------------------------------------------------------- Source/runEnv/RunDecl.java ---------------------------------------------------------------- package runEnv; import java.util.*; public class RunDecl { public final static int NONE = 0; public final static int VALUE = 1; public final static int PATH = 2; public final static int COMPONENT = 3; public final static int INPUTPARAM = 4; public final static int OUTPUTPARAM = 5; public final static int VALUEPARAM = 6; public static String kindText( int kind ) { switch ( kind ) { case NONE: return "NONE"; case VALUE: return "VALUE"; case PATH: return "PATH"; case COMPONENT: return "COMPONENT"; case VALUEPARAM: return "VALUEPARAM"; case INPUTPARAM: return "INPUTPARAM"; case OUTPUTPARAM: return "OUTPUTPARAM"; default: return "" + kind; } } private int kind; private String ident; private RunValue value; public int kind() { return kind; } public String kindText() { return kindText( kind ); } public String ident() { return ident; } public RunValue value() { return value; } public RunDecl( int kind, String ident, RunValue value ) { this.kind = kind; this.ident = ident; this.value = value; // System.err.println( this ); } public String toString() { return "Declare " + kindText() + ":\t" + ident + "\t" + value; } } ---------------------------------------------------------------- Source/runEnv/RunEnv.java ---------------------------------------------------------------- package runEnv; import builtin.*; import java.util.*; public class RunEnv { private String name; private RunEnv enclosingEnv; private Vector< RunDecl > locals = new Vector< RunDecl >(); public String name() { return name; } private RunEnv enclosingEnv() { return enclosingEnv; } private int size() { return locals.size(); } private RunDecl elementAt( int i ) { return locals.elementAt( i ); } public RunEnv( String name, RunEnv enclosingEnv ) { this.name = name; this.enclosingEnv = enclosingEnv; } private RunDecl searchLocal( String ident ) { for ( int i = 0; i < size(); i++ ) { RunDecl decl = elementAt( i ); if ( ident.equals( decl.ident() ) ) return decl; } return null; } public void declare( int kind, String ident, RunValue value ) { if ( searchLocal( ident ) != null ) throw new Error( "Identifier " + ident + " redeclared" ); locals.add( new RunDecl( kind, ident, value ) ); } public RunValue getValue( String ident ) { RunDecl decl = searchLocal( ident ); if ( decl != null ) return decl.value(); else if ( enclosingEnv == null ) throw new Error( "Identifier " + ident + " undeclared" ); else return enclosingEnv.getValue( ident ); } public void addListener( Component component ) { for ( int i = 0; i < size(); i++ ) { RunDecl decl = elementAt( i ); if ( decl.kind() == RunDecl.INPUTPARAM ) decl.value().pathArrayValue().addListener( component ); } } public String toString() { String result = name + ":\n";; for ( int i = 0; i < size(); i++ ) { RunDecl decl = elementAt( i ); result += "\t" + decl + "\n"; } return result; } } ---------------------------------------------------------------- Source/runEnv/basicValue/PathValue.java ---------------------------------------------------------------- package runEnv.basicValue; import runEnv.*; import builtin.*; import java.util.*; public class PathValue extends BasicValue { private static int pathNumGenerator = 0; private int pathNum; private boolean value; private Vector< Component > listeners = new Vector< Component >(); public PathValue( int pathNum ) { this.pathNum = pathNum; } public PathValue() { this.pathNum = pathNumGenerator++; } public PathValue pathValue() { return this; } public int pathNum() { return pathNum; } public boolean isPath() { return true; } public boolean equals( Object other ) { if ( other == null ) return false; if ( ! ( other instanceof RunValue ) ) return false; RunValue runValue = ( RunValue ) other; if ( ! ( runValue instanceof PathValue ) ) return false; PathValue otherPathValue = ( PathValue ) runValue; return pathNum() == otherPathValue.pathNum(); } public String toString() { return "" + pathNum; } public boolean getValue() { return value; } public void setValue( boolean value ) { // System.err.println( "setValue " + value + " for " + this ); if ( value != this.value ) { this.value = value; for ( int i = 0; i < listeners.size(); i++ ) { Component component = listeners.elementAt( i ); component.schedule(); } } } public void addListener( Component component ) { // System.err.println( "addListener " + component + " for " + this ); listeners.add( component ); } } ---------------------------------------------------------------- Source/runEnv/PathArrayValue.java ---------------------------------------------------------------- package runEnv; import runEnv.basicValue.*; import builtin.*; public class PathArrayValue extends RunValue { private PathValue[] base; private PathValue[] base() { return base; } private int offset; private int offset() { return offset; } private int size; public int size() { return size; } public PathValue elementAt( int i ) { if ( i < 0 || i >= size ) throw new Error( "Invalid index of " + i + " for PathArrayValue " + this ); return base[ offset + i ]; } public PathArrayValue( int size ) { if ( size < 0 ) throw new Error( "Invalid PathArrayValue( " + size + " )" ); base = new PathValue[ size ]; this.size = size; this.offset = 0; for ( int i = 0; i < size; i++ ) base[ i ] = new PathValue(); // System.err.println( "Creating PathArrayValue( " + size + " ) " + this ); } private PathArrayValue( PathValue[] base, int offset, int size ) { if ( offset < 0 || size < 0 || offset + size > base.length ) throw new Error( "Invalid PathArrayValue( base " + base.length + ", " + offset + ", " + size + " )" ); this.base = base; this.offset = offset; this.size = size; // System.err.println( "Creating PathArrayValue( " + offset + ", " + size + " ) " + this ); } public PathArrayValue( PathArrayValue[] value ) { size = 0; for ( int i = 0; i < value.length; i++ ) { PathArrayValue element = value[ i ]; size += element.size(); } base = new PathValue[ size ]; int k = 0; for ( int i = value.length - 1; i >= 0; --i ) { PathArrayValue element = value[ i ]; for ( int j = 0; j < element.size(); j++ ) base[ k++ ] = element.elementAt( j ); } /* System.err.println( "Creating PathArrayValue " + this + " from " ); for ( int i = 0; i < value.length; i++ ) { PathArrayValue element = value[ i ]; System.err.println( "\t" + element ); } */ } public PathArrayValue pathArrayValue() { return this; } public boolean isPathArray() { return true; } public boolean equals( Object other ) { if ( other == null ) return false; if ( ! ( other instanceof RunValue ) ) return false; RunValue runValue = ( RunValue ) other; if ( ! ( runValue instanceof PathArrayValue ) ) return false; PathArrayValue otherArrayValue = ( PathArrayValue ) runValue; return base == otherArrayValue.base() && offset == otherArrayValue.offset() && size == otherArrayValue.size(); } public String toString() { String result = ""; if ( size() == 0 ) return "{}"; for ( int i = 0; i < size(); i++ ) { if ( i > 0 ) result += ", "; result += elementAt( i ); } return "{ " + result + " }"; } public PathArrayValue index( int start ) { if ( start < 0 || start >= size ) throw new Error( "index out of bounds" ); return new PathArrayValue( base, this.offset + start, 1 ); } public PathArrayValue subArray( int start, int size ) { if ( start < 0 || size < 0 || start + size > this.size ) throw new Error( "subarray " + this + "[ " + size + " @ " + start + " ] out of bounds" ); return new PathArrayValue( base, this.offset + start, size ); } public long getValue() { long value = 0; for ( int i = 0; i < size(); i++ ) { if ( elementAt( i ).getValue() ) value |= 1L << i; } // System.err.println( "getValue " + Long.toString( value, 16 ) ); return value; } public void setValue( long value ) { // System.err.println( "setValue " + Long.toString( value, 16 ) ); for ( int i = 0; i < size(); i++ ) { elementAt( i ).setValue( ( value & ( 1L << i ) ) != 0 ); } } public void setValue( PathArrayValue otherArrayValue ) { // System.err.println( "setValue " + otherArrayValue ); for ( int i = 0; i < size(); i++ ) { boolean value = otherArrayValue.elementAt( i ).getValue(); elementAt( i ).setValue( value ); } } public void addListener( Component component ) { for ( int i = 0; i < size(); i++ ) { PathValue path = elementAt( i ); path.addListener( component ); } } } ---------------------------------------------------------------- Source/runEnv/ComponentValue.java ---------------------------------------------------------------- package runEnv; import node.declNode.componentDeclNode.*; public class ComponentValue extends RunValue { private ComponentDeclNode componentDecl; private RunEnv enclosingEnv; public ComponentDeclNode componentDecl() { return componentDecl; } public ComponentValue( ComponentDeclNode componentDecl, RunEnv enclosingEnv ) { this.componentDecl = componentDecl; this.enclosingEnv = enclosingEnv; } public ComponentValue componentValue() { return this; } public boolean isComponent() { return true; } public boolean equals( Object other ) { if ( other == null ) return false; if ( ! ( other instanceof RunValue ) ) return false; RunValue runValue = ( RunValue ) other; if ( ! ( runValue instanceof ComponentValue ) ) return false; ComponentValue otherComponentValue = ( ComponentValue ) runValue; return this == otherComponentValue; } public String toString() { return componentDecl.ident(); } public void eval( PathArrayValue[] inputParamValues, RunValue[] paramValues, PathArrayValue[] outputParamValues ) { componentDecl.invoke( enclosingEnv, inputParamValues, paramValues, outputParamValues ); } } ---------------------------------------------------------------- Source/builtin/Component.java ---------------------------------------------------------------- package builtin; import runEnv.*; public abstract class Component extends Thread { private boolean changed = false; private RunEnv runEnv; public RunEnv runEnv() { return runEnv; } public Component( RunEnv runEnv ) { this.runEnv = runEnv; runEnv.addListener( this ); } public void run() { while ( true ) { compute(); pause(); } } public abstract void compute(); public synchronized void pause() { if ( ! changed ) try { wait(); } catch ( InterruptedException exception ) { } changed = false; } public synchronized void schedule() { changed = true; notify(); } } ---------------------------------------------------------------- Source/builtin/AndComponent.java ---------------------------------------------------------------- package builtin; import runEnv.*; public class AndComponent extends Component { public AndComponent( RunEnv runEnv ) { super( runEnv ); } public void compute() { int n = runEnv().getValue( "n" ).intValue(); PathArrayValue opd = runEnv().getValue( "opd" ).pathArrayValue(); PathArrayValue result = runEnv().getValue( "result" ).pathArrayValue(); boolean resultValue = true; for ( int i = 0; i < n; i++ ) resultValue &= opd.elementAt( i ).getValue(); result.elementAt( 0 ).setValue( resultValue ); } }