initial import
git-svn-id: svn://anubis/jtlc/trunk@2 f5bc74b8-7b62-4e90-9214-7121d538519f
This commit is contained in:
parent
8bfe25effa
commit
01bd481bce
30
Makefile
Normal file
30
Makefile
Normal 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
24
lib/lang/String.jtl
Normal 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
6
lib/std/io.jtl
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
module std.io;
|
||||
|
||||
print(...) : void
|
||||
{
|
||||
}
|
23
main/Makefile
Normal file
23
main/Makefile
Normal 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
8
main/jtlc.cc
Normal 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
37
parser/Makefile
Normal 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
85
parser/parser.lex
Normal 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
130
parser/parser.yy
Normal 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
12
tests/HelloWorld.jtl
Normal 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
37
tests/Interpolator.jtl
Normal 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
40
tests/Regex.jtl
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user