initial import

git-svn-id: svn://anubis/jtlc/trunk@2 f5bc74b8-7b62-4e90-9214-7121d538519f
This commit is contained in:
josh 2009-03-28 15:17:48 +00:00
parent 8bfe25effa
commit 01bd481bce
11 changed files with 432 additions and 0 deletions

30
Makefile Normal file
View File

@ -0,0 +1,30 @@
SHELL := bash
TARGET := jtlc
ifdef WIN32
export CPPFLAGS += -I"$(shell cd)"
else
export CPPFLAGS += -I"$(shell pwd)"
endif
export CXXFLAGS := -Wall -O2
LDFLAGS := -lfl
SUBDIRS := main parser
all: $(TARGET)
.PHONY: $(TARGET)
$(TARGET):
@for d in $(SUBDIRS); \
do $(MAKE) -C $$d; \
ret=$$?; \
if [[ $$ret != 0 ]]; then \
exit $$ret; \
fi; \
done
$(CXX) -o $@ $(patsubst %,%/*.o,$(SUBDIRS)) $(CXXFLAGS) $(LDFLAGS)
clean:
for d in $(SUBDIRS); do $(MAKE) -C $$d clean CLEAN=1; done
-rm -f $(TARGET)

24
lib/lang/String.jtl Normal file
View File

@ -0,0 +1,24 @@
module String;
private m_chars : char[];
String(chars : char[])
{
m_chars := chars;
}
length() : int
{
return m_chars.length;
}
operator+(str1 : String, str2 : String) : String
{
chars : char[] := new char[str1.length() + str2.length()];
}
operator=~(str1 : String, str2 : String) : bool
{
return true;
}

6
lib/std/io.jtl Normal file
View File

@ -0,0 +1,6 @@
module std.io;
print(...) : void
{
}

23
main/Makefile Normal file
View File

@ -0,0 +1,23 @@
OBJS := $(patsubst %.cc,%.o,$(wildcard *.cc))
DEPS := $(OBJS:.o=.dep)
all: $(DEPS) $(OBJS)
%.o: %.cc
$(CXX) -c -o $@ $(CPPFLAGS) $(CXXFLAGS) $<
# Make dependency files
%.dep: %.cc
@set -e; rm -f $@; \
$(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
clean:
-$(RM) -f *.o *.dep
# Include dependency files
ifndef CLEAN
-include $(DEPS)
endif

8
main/jtlc.cc Normal file
View File

@ -0,0 +1,8 @@
#include <stdio.h>
int main(int argc, char * argv[])
{
printf("jtlc, version 0.00000001\n");
return 0;
}

37
parser/Makefile Normal file
View File

@ -0,0 +1,37 @@
FLEX := flex
BISON := bison
PARSER := parser
OBJS := lex.yy.o $(PARSER).tab.o $(patsubst %.cc,%.o,$(wildcard *.cc))
DEPS := $(OBJS:.o=.dep)
all: $(DEPS) $(OBJS)
%.o: %.cc
$(CXX) -c -o $@ $(CPPFLAGS) $(CXXFLAGS) $<
$(PARSER).tab.cc $(PARSER).tab.hh: $(PARSER).yy
$(BISON) -d $<
lex.yy.o: lex.yy.cc
lex.yy.cc: $(PARSER).tab.hh
lex.yy.cc: $(PARSER).lex
$(FLEX) -o $@ $<
# Make dependency files
%.dep: %.cc
@set -e; rm -f $@; \
$(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
clean:
-rm -f lex.yy.cc $(PARSER).tab.cc $(PARSER).tab.hh *~ *.o *.dep
# Include dependency files
ifndef CLEAN
-include $(DEPS)
endif

85
parser/parser.lex Normal file
View File

@ -0,0 +1,85 @@
%option nounput
%option bison-locations
%{
#include "parser.tab.hh"
%}
%%
/* operators */
:= return ASSIGN;
== return DEQUALS;
\/ return DIVIDE;
= return EQUALS;
\> return GREATER;
\< return LESS;
=~ return MATCH;
- return MINUS;
% return MOD;
\+ return PLUS;
\* return STAR;
/* punctuation */
: return COLON;
, return COMMA;
:: return DCOLON;
\$ return DOLLAR;
\. return DOT;
\<- return FROM;
\? return QUESTION;
; return SEMICOLON;
\{ return LCURLY;
\} return RCURLY;
\[ return LBRACKET;
\] return RBRACKET;
\( return LPAREN;
\) return RPAREN;
/* literals */
-?[0-9]+ {
return INT_LITERAL;
}
-?0x[0-9]+ {
return INT_LITERAL;
}
-?0b[01]+ {
return INT_LITERAL;
}
-?[0-9]*\.[0-9]+([eE][0-9]+)? {
return REAL_LITERAL;
}
/* primitive types */
byte return BYTE;
ubyte return UBYTE;
char return CHAR;
wchar return WCHAR;
int return INT;
uint return UINT;
long return LONG;
ulong return ULONG;
/* keywords */
import return IMPORT;
module return MODULE;
return return RETURN;
struct return STRUCT;
/* identifiers */
[a-zA-Z_][a-zA-Z_0-9]* {
return IDENTIFIER;
}
/* whitespace */
\n yylloc->first_line++; yylloc->last_line++;
[ \t\v] /* ignore whitespace */
/* anything else */
. return yytext[0];
%%

130
parser/parser.yy Normal file
View File

@ -0,0 +1,130 @@
%{
#include <stdio.h>
#include <iostream>
#include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */
using namespace std;
#define yyerror(msg) errFunc(msg, &yylloc)
int yylex(YYSTYPE *, YYLTYPE *);
extern FILE * yyin;
void errFunc(const char * str, YYLTYPE * yyllocp);
int yywrap()
{
return 1;
}
%}
%pure-parser
%locations
%error-verbose
/* operators */
%token ASSIGN;
%token DEQUALS;
%token DIVIDE;
%token EQUALS;
%token GREATER;
%token LESS;
%token MATCH;
%token MINUS;
%token MOD;
%token PLUS;
%token STAR;
/* punctuation */
%token COLON;
%token COMMA;
%token DCOLON;
%token DOLLAR;
%token DOT;
%token FROM;
%token QUESTION;
%token SEMICOLON;
%token LCURLY;
%token RCURLY;
%token LBRACKET;
%token RBRACKET;
%token LPAREN;
%token RPAREN;
/* literals */
%token INT_LITERAL;
%token REAL_LITERAL;
/* primitive types */
%token BYTE;
%token UBYTE;
%token CHAR;
%token WCHAR;
%token INT;
%token UINT;
%token LONG;
%token ULONG;
/* keywords */
%token IMPORT;
%token MODULE;
%token RETURN;
%token STRUCT;
/* identifiers */
%token IDENTIFIER;
%%
program: INT_LITERAL
;
primitive_type: BYTE
| UBYTE
| CHAR
| WCHAR
| INT
| UINT
| LONG
| ULONG
;
struct_type: STRUCT
;
ptr_type: type STAR
;
type: primitive_type
| ptr_type
| struct_type
;
%%
void parse(const char * fileName)
{
yyin = fopen(fileName, "r");
if (yyin == NULL)
{
cerr << "Failed to open file '" << fileName << "'" << endl;
return;
}
if (yyparse())
{
cerr << "Aborting." << endl;
exit(1);
}
}
void errFunc(const char * str, YYLTYPE * yyllocp)
{
fprintf(stderr, "error: %s: line %d, column %d\n",
str,
yyllocp->first_line,
yyllocp->first_column);
}

12
tests/HelloWorld.jtl Normal file
View File

@ -0,0 +1,12 @@
import std.io.*;
int main(args : String[])
{
foreach (arg <- args)
println("arg: ", arg);
println("Hello, World!\n");
return 0;
}

37
tests/Interpolator.jtl Normal file
View File

@ -0,0 +1,37 @@
module Interpolator;
import std.io.*;
typedef function double (double) interpolator_t;
int main(args : String[])
{
interpolator_t i1 = getInterpolator(1, 5, 4);
interpolator_t i2 = getInterpolator(10, 2, 5);
assert( i1(0) =~ 1 );
assert( i1(4) =~ 5 );
assert( i1(3) =~ 4.0 );
assert( i2(0) =~ 10 );
assert( i2(5) =~ 2 );
assert( i2(1.0) =~ 8.4 );
assert( i2(2.0) =~ 6.8 );
return 0;
}
/*
* Create and return a linear interpolator functor which interpolates
* between (0.0, x1) and (sep, x2), returning the output y-value
*/
interpolator_t getInterpolator(x1 : double, x2 : double, sep : double)
{
assert (sep > 0.0);
return function double (x : double)
{
return x * (x2 - x1) / sep + x1;
}
}

40
tests/Regex.jtl Normal file
View File

@ -0,0 +1,40 @@
module Regex;
import std.io.*;
int main(args : String[])
{
foreach (arg <- args)
{
/* operator=~(String, String) returns an array of String results for
* the matches. When there are no explicit parentheses in a pattern,
* the array returned contains just one string - the entire matched
* content. If the pattern does not match, an empty array is returned.
* An empty array evaluations in a boolean context to false, while an
* array with a nonzero number of arguments evaluations to true.
* Hence, the =~ operator can be used in an if() statement to see if
* the string matches a given pattern
*/
if (arg =~ "/^\d+$/")
{
println(arg, " is a number");
}
else if (arg =~ "/^0x\d+$/i")
{
println(arg, " is a hexadecimal number");
}
else
{
/* auto declaration of matches to be of type String[] */
matches ::= arg =~ "/(.)(.)/";
if (matches)
{
println("first character: ", matches[0],
"second character: ", matches[1]);
}
}
}
return 0;
}