The GG Programming Language
description
Transcript of The GG Programming Language
The GG Programming The GG Programming LanguageLanguage
““We give it to you.”We give it to you.”
The AuthorsThe Authors
Kierstan BellKierstan Bell• Documentation and Front-endDocumentation and Front-end
Elizabeth MutterElizabeth Mutter• Front-endFront-end
Jake PorwayJake Porway• Testing and Front-endTesting and Front-end
Jonah TowerJonah Tower• Back-endBack-end
Language OverviewLanguage Overview
JonahJonah
Why GG?Why GG?
……it makes things easy!it makes things easy!
SocketsSockets I/OI/O ThreadsThreads
Sockets a Simple ClientSockets a Simple Client#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <string.h>#include <string.h>#include <unistd.h>#include <unistd.h>#include <signal.h>#include <signal.h>#include <errno.h>#include <errno.h>#include <sys/types.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/socket.h>#include <sys/wait.h>#include <sys/wait.h>#include <netinet/in.h>#include <netinet/in.h>
/* sklar: need to define socklen_t for cunix; not needed for linux *//* sklar: need to define socklen_t for cunix; not needed for linux *//* typedef int socklen_t; *//* typedef int socklen_t; */
#define TERM '\n'#define TERM '\n'
/*--------------------------------------------------------------------/*-------------------------------------------------------------------- sysabort()sysabort()
system error occured; reports error and exits programsystem error occured; reports error and exits program ------------------------------------------------------------------*/------------------------------------------------------------------*/void sysabort ( char *m ) { void sysabort ( char *m ) { perror( m ); perror( m ); exit( 1 );exit( 1 );} /* end of sysabort() */} /* end of sysabort() */
/*--------------------------------------------------------------------/*-------------------------------------------------------------------- client_sock()client_sock()
creates a socket and then attempts to make a connection to that creates a socket and then attempts to make a connection to that socketsocket ------------------------------------------------------------------*/------------------------------------------------------------------*/int client_sock ( int port ) {int client_sock ( int port ) {
int ss, optval = 1;int ss, optval = 1; struct sockaddr_in sin;struct sockaddr_in sin;
/* (1) create an endpoint for communication *//* (1) create an endpoint for communication */ if (( ss = socket( PF_INET, SOCK_STREAM, 0 )) == -1) {if (( ss = socket( PF_INET, SOCK_STREAM, 0 )) == -1) {
sysabort( "client/socket" );sysabort( "client/socket" ); }}
/* (1a) set socket options *//* (1a) set socket options */ if ( setsockopt( ss,if ( setsockopt( ss,
SOL_SOCKET, SOL_SOCKET, SO_REUSEADDR, /* basically allows SO_REUSEADDR, /* basically allows
socket to bind */socket to bind */ /*(const char *)&optval, sizeof(optval)) /*(const char *)&optval, sizeof(optval))
== -1 ) {*/== -1 ) {*/ &optval, sizeof(optval)) == -1 ) {&optval, sizeof(optval)) == -1 ) {
sysabort( "client/setsockopt" );sysabort( "client/setsockopt" ); }} memset( &sin, 0, sizeof( sin ));memset( &sin, 0, sizeof( sin )); sin.sin_family = AF_INET;sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl( INADDR_LOOPBACK );sin.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); sin.sin_port = port;sin.sin_port = port;
This is Really SimpleThis is Really Simple/* (2) make a connection to the server socket *//* (2) make a connection to the server socket */ if ( connect( ss,(struct sockaddr *)&sin,(socklen_t)sizeof(sin) ) == -1 ) {if ( connect( ss,(struct sockaddr *)&sin,(socklen_t)sizeof(sin) ) == -1 ) { printf("foobar\n");printf("foobar\n");
sysabort( "client/connect" );sysabort( "client/connect" ); }}
/* return the socket descriptor *//* return the socket descriptor */ return( ss );return( ss );
} /* end of client_sock() */} /* end of client_sock() */
/*--------------------------------------------------------------------/*-------------------------------------------------------------------- echo_client()echo_client() ------------------------------------------------------------------*/------------------------------------------------------------------*/void echo_client ( int port ) {void echo_client ( int port ) {
int sock, olen, nwritten, nread, more;int sock, olen, nwritten, nread, more; unsigned char i;unsigned char i; char ibuf[64], obuf[64], *p;char ibuf[64], obuf[64], *p; /* create client socket on port... *//* create client socket on port... */ printf( "client: port=%d\n",port );printf( "client: port=%d\n",port ); sock = client_sock( port );sock = client_sock( port ); /* loop, reading input from client and sending it to server *//* loop, reading input from client and sending it to server */ more = 1;more = 1; while ( more ) {while ( more ) {
printf( "enter message to send (q to quit): " );printf( "enter message to send (q to quit): " );p = obuf;p = obuf;p = fgets( p,64,stdin );p = fgets( p,64,stdin );p[strlen(p)-1] = '\0';p[strlen(p)-1] = '\0';if ( p[0] == 'q' ) {if ( p[0] == 'q' ) { more = 0;more = 0;
p[0] = TERM;p[0] = TERM; p[1] = '\0';p[1] = '\0';}}else {else { printf( "client: writing message [%s]\n",p );printf( "client: writing message [%s]\n",p ); i = strlen( p );i = strlen( p );}}if (( nwritten = write( sock, &i, sizeof( i ) )) == -1 ) {if (( nwritten = write( sock, &i, sizeof( i ) )) == -1 ) { sysabort( "client/write" );sysabort( "client/write" );}}if (( nwritten = write( sock, p, strlen(p) )) == -1 ) {if (( nwritten = write( sock, p, strlen(p) )) == -1 ) { sysabort( "client/write" );sysabort( "client/write" );}}if ( more ) {if ( more ) { if (( nread = read( sock, &i, sizeof( i ))) < 0 ) {if (( nread = read( sock, &i, sizeof( i ))) < 0 ) {
sysabort( "client/read" );sysabort( "client/read" ); }} fprintf( stdout,"client: i=%d\n",i );fprintf( stdout,"client: i=%d\n",i ); fflush( stdout );fflush( stdout ); if (( nread = read( sock, ibuf, i )) < 0 ) {if (( nread = read( sock, ibuf, i )) < 0 ) {
sysabort( "client/read" );sysabort( "client/read" ); }} ibuf[nread] = '\0';ibuf[nread] = '\0'; if ( ibuf[0] == TERM ) {if ( ibuf[0] == TERM ) {
more = 0;more = 0; }} else {else {
fprintf( stdout,"client: read message [%s]\fprintf( stdout,"client: read message [%s]\n",ibuf );n",ibuf );
fflush( stdout );fflush( stdout ); }}}}
} /* end while more */} /* end while more */ /* close socket connection *//* close socket connection */ close( sock );close( sock );
……Still goingStill going
} /* end of echo_client() */} /* end of echo_client() */
/*--------------------------------------------------------------------/*--------------------------------------------------------------------
main()main()
------------------------------------------------------------------*/------------------------------------------------------------------*/
int main( int argc, char *argv[] ) {int main( int argc, char *argv[] ) {
int port;int port;
if ( argc < 2 ) {if ( argc < 2 ) {
printf( "usage: client.x <port>\n" );printf( "usage: client.x <port>\n" );
exit( 1 );exit( 1 );
}}
sscanf( argv[1],"%d",&port );sscanf( argv[1],"%d",&port );
echo_client( port );echo_client( port );
return( 0 );return( 0 );
} /* end of main() */} /* end of main() */
And now in GGAnd now in GG
void main(string arg1, string arg2){void main(string arg1, string arg2){sockconnect(arg1, stoi(arg2));sockconnect(arg1, stoi(arg2));while(1){while(1){
send(getline());send(getline());print(recv());print(recv());
}}}}
File I/O (in Java)File I/O (in Java)
File f = new File(“foobar.txt”);File f = new File(“foobar.txt”);
File I/O (in Java)File I/O (in Java)
File f = new File(“foobar.txt”);File f = new File(“foobar.txt”);
FileReader fr = new FileReader(f);FileReader fr = new FileReader(f);
File I/O (in Java)File I/O (in Java)
File f = new File(“foobar.txt”);File f = new File(“foobar.txt”);
FileReader fr = new FileReader(f);FileReader fr = new FileReader(f);
BufferedReader in = new BufferedReader in = new BufferedReader(fr);BufferedReader(fr);
File I/O (in Java)File I/O (in Java)
File f = new File(“foobar.txt”);File f = new File(“foobar.txt”);
FileReader fr = new FileReader(f);FileReader fr = new FileReader(f);
BufferedReader in = new BufferedReader in = new BufferedReader(fr);BufferedReader(fr);
String line = in.readLine();String line = in.readLine();
……but wait!but wait!
try{try{
File f = new File(“foobar.txt”);File f = new File(“foobar.txt”);
FileReader fr = new FileReader(f);FileReader fr = new FileReader(f);
BufferedReader in = new BufferedReader in = new BufferedReader(fr);BufferedReader(fr);
String line = in.readLine();String line = in.readLine();
}}
Catch(IOException e){Catch(IOException e){
System.err.println(“Oh no!”);System.err.println(“Oh no!”);
}}
Look at our Cool VersionLook at our Cool Version
file f = “foobar.txt”;file f = “foobar.txt”;
string line = fgetline(f);string line = fgetline(f);
And, GG lets youAnd, GG lets youthread thingsthread things
WOW!WOW!
Syntax and SemanticsSyntax and Semantics
KierstanKierstan
This is Like C, Baby!This is Like C, Baby!
Functional languageFunctional language NOT Object OrientedNOT Object Oriented C-like syntaxC-like syntax
int x;
int foo(int i)
{
int y;
y = i + 1;
return y;
}
void main()
{
int z;
x = 10;
z = foo(x);
}
Data TypesData Types
booleanbooleanboolean b = true;boolean b = true;boolean b = false;boolean b = false;
charchar char a = ‘a’;char a = ‘a’;
filefile file myFile = “myFile.txt”file myFile = “myFile.txt”
intint int i = 0;int i = 0;
stringstring string hi = “hi”;string hi = “hi”;
Control FlowControl Flow
while statementwhile statement
ifif
while(<boolean>){
statements;
}
if(<boolean>){
statements;
}
Built-in FunctionsBuilt-in Functions string fgetline(file f)string fgetline(file f) void fprint(file f, string option, string line)void fprint(file f, string option, string line) int getint()int getint() string getline()string getline() string getlocalhost()string getlocalhost() int getTime()int getTime() void print(string line)void print(string line) string recv()string recv() string recv(int port)string recv(int port) void send(file file)void send(file file) void send(file file, int port)void send(file file, int port) void send(string line)void send(string line) void send(string line, int port)void send(string line, int port) void socketclose()void socketclose() void socketclose(int port)void socketclose(int port) int socketcreate()int socketcreate() int socketcreate(int port)int socketcreate(int port) int socketconnect(int port)int socketconnect(int port) int socketconnect(string host, int port)int socketconnect(string host, int port) int stoi(string s)int stoi(string s)
Threaded FunctionsThreaded Functions
threaded void funcA(){threaded void funcA(){
print(“a”);print(“a”);
}}
threaded void funcB(){threaded void funcB(){
print(“b”);print(“b”);
}}
The CompilerThe Compiler
ElizabethElizabeth
Lexer
Parser
SemanticChecker
CodeGenerator
Call GGcompiler
GG code file
Guts Package
ErrorMessageReporting
JavacCompiler
Java file
Java Class
Symbol table:
FunctionsGlobalsLocals
Lexer/ParserLexer/Parser
Both written in ANTLRBoth written in ANTLR Lexer Lexer
• Parses a GG file into TokensParses a GG file into Tokens ParserParser
• Takes the Lexer’s tokens as inputTakes the Lexer’s tokens as input• Checks for syntax errorsChecks for syntax errors• Creates a treeCreates a tree
Building the Tree Building the Tree
For example - For example -
GG assignment GG assignment statement:statement:
a = myFunc();a = myFunc();
ASSIGN
=
FUNCDECLa
myFunc
Walking the TreeWalking the Tree Semantic check AND code generation done in one Semantic check AND code generation done in one
passpass Uses ANTLR’s tree walker Uses ANTLR’s tree walker
• Walks the dummy nodesWalks the dummy nodes• … … but java code does most of the workbut java code does most of the work
Semantic:Semantic:• Hashtables keep track of :Hashtables keep track of :
Global variablesGlobal variables Local variablesLocal variables Function declarationsFunction declarations KeywordsKeywords
Code:Code:• Prints java code to .java filesPrints java code to .java files
Code Generation: Java FilesCode Generation: Java Files
[name-of-file].java[name-of-file].java• Runnable java fileRunnable java file
[name-of-file]MainMethod.java[name-of-file]MainMethod.java• Wrapper class that contains the Wrapper class that contains the
translated GG codetranslated GG code [name-of-function]ThreadedFunction.java[name-of-function]ThreadedFunction.java
• Created for each threaded function Created for each threaded function
Testing and Lessons Testing and Lessons LearnedLearned
JakeJake
Standard Regression TestingStandard Regression Testing
No surprises here…No surprises here…
• Small modules tested against base Small modules tested against base cases using scriptcases using script
Syntactic tests run with Lexer/ParserSyntactic tests run with Lexer/Parser Semantic tests run with Tree WalkerSemantic tests run with Tree Walker Generated code checks run by handGenerated code checks run by hand
Syntactic Error CheckingSyntactic Error Checking• Checks syntax in Lexer/ParserChecks syntax in Lexer/Parser• Basic syntactic errors introduced into correct Basic syntactic errors introduced into correct
reference casesreference cases• Resulting trees are comparedResulting trees are compared
Base CaseBase Casevoid main()
{
int a = 3; (FUNC_DECL void main (BODY (= a 3)))}
ErrorErrorvoid main()
{
int a = 3 “Expected SEMI found CCURLY”
}
Semantic Error CheckingSemantic Error Checking• Only need to check select semantic Only need to check select semantic
errors, since most egregious errors are errors, since most egregious errors are syntacticsyntactic
• Keep log of test results, check for failureKeep log of test results, check for failure
void main()
{
int a = “Not a string”;
}
Prints to log file:Prints to log file:
test1-typecheck-incorrect.gg
Result: “Expected type int but got ‘Not a string’”
Code CorrectnessCode Correctness
• Not done with automated checkingNot done with automated checking
• No mortal should have to hand-generate No mortal should have to hand-generate the Java base case for a client/server the Java base case for a client/server programprogram
• Instead, functionality is checked Instead, functionality is checked thoroughly, not codethoroughly, not code
Lessons Learned!Lessons Learned!
Roles are great, but don’t be afraid Roles are great, but don’t be afraid to “diversify”to “diversify”
Meetings, meetings, and more Meetings, meetings, and more meetings! There’s comfort in meetings! There’s comfort in consistencyconsistency
Clairvoyance – Who knew ANTLR Clairvoyance – Who knew ANTLR would be so hardwould be so hard
Ctrl-1-0-0 – Who put this in Emacs?Ctrl-1-0-0 – Who put this in Emacs?
THE ENDTHE END