Merge branch 'master' into newlisp

This commit is contained in:
Paul Chaignon
2014-12-06 17:50:37 -05:00
227 changed files with 56990 additions and 31948 deletions

367
samples/APL/UT.dyalog Normal file
View File

@@ -0,0 +1,367 @@
:NameSpace UT
sac ← 0
expect_orig ← expect ← ⎕NS⍬
exception ← ⍬
nexpect_orig ← nexpect ← ⎕NS⍬
∇ {Z}←{Conf}run Argument;PRE_test;POST_test;TEST_step;COVER_step;FromSpace
load_display_if_not_already_loaded
load_salt_scripts_into_current_namespace_if_configured
FromSpace←1⊃⎕RSI
PRE_test←{}
POST_test←{}
COVER_step←{}
:If 0≠⎕NC'Conf'
:If Conf has'cover_target'
PRE_test←{{}⎕PROFILE'start'}
POST_test←{{}⎕PROFILE'stop'}
:EndIf
:EndIf
:If is_function Argument
TEST_step←single_function_test_function
COVER_file←Argument,'_coverage.html'
:ElseIf is_list_of_functions Argument
TEST_step←list_of_functions_test_function
COVER_file←'list_coverage.html'
:ElseIf is_file Argument
TEST_step←file_test_function
COVER_file←(get_file_name Argument),'_coverage.html'
:ElseIf is_dir Argument
test_files←test_files_in_dir Argument
TEST_step←test_dir_function
Argument←test_files
:EndIf
:If 0≠⎕NC'Conf'
:If Conf has'cover_target'
COVER_step←{Conf,←⊂('cover_file'COVER_file)
generate_coverage_page Conf}
:EndIf
:EndIf
PRE_test ⍬
Z←FromSpace TEST_step Argument
POST_test ⍬
COVER_step ⍬
∇ load_display_if_not_already_loaded
:If 0=⎕NC'#.DISPLAY'
'DISPLAY'#.⎕CY'display'
:EndIf
∇ load_salt_scripts_into_current_namespace_if_configured
:If 0≠⎕NC'#.UT.appdir'
:If ⍬≢#.UT.appdir
⎕SE.SALT.Load #.UT.appdir,'src/*.dyalog -target=#'
⎕SE.SALT.Load #.UT.appdir,'test/*.dyalog -target=#'
:EndIf
:EndIf
∇ Z←FromSpace single_function_test_function TestName
Z←run_ut FromSpace TestName
∇ Z←FromSpace list_of_functions_test_function ListOfNames;t
t←⎕TS
Z←run_ut¨{FromSpace ⍵}¨ListOfNames
t←⎕TS-t
('Test execution report')print_passed_crashed_failed Z t
∇ Z←FromSpace file_test_function FilePath;FileNS;Functions;TestFunctions;t
FileNS←⎕SE.SALT.Load FilePath,' -target=#'
Functions←↓FileNS.⎕NL 3
TestFunctions←(is_test¨Functions)/Functions
:If (0/⍬,⊂0/'')≡TestFunctions
⎕←'No test functions found'
Z←⍬
:Else
t←⎕TS
Z←run_ut¨{FileNS ⍵}¨TestFunctions
t←⎕TS-t
(FilePath,' tests')print_passed_crashed_failed Z t
:EndIf
∇ Z←FromSpace test_dir_function Test_files
:If Test_files≡⍬/⍬,⊂''
⎕←'No test files found'
Z←⍬
:Else
Z←#.UT.run¨Test_files
:EndIf
∇ Z←get_file_name Argument;separator
separator←⊃⌽(Argument∊'/\')/Argument
Z←¯7↓separator↓Argument
∇ generate_coverage_page Conf;ProfileData;CoverResults;HTML
ProfileData←⎕PROFILE'data'
ToCover←retrieve_coverables¨(⊃'cover_target'in Conf)
:If (ToCover)≡(⊂1)
ToCover←⊃ToCover
:EndIf
Representations←get_representation¨ToCover
CoverResults←ProfileData∘generate_cover_result¨↓ToCover,[1.5]Representations
HTML←generate_html CoverResults
Conf write_html_to_page HTML
⎕PROFILE'clear'
∇ Z←retrieve_coverables Something;nc;functions
nc←⎕NC Something
:If nc=3
Z←Something
:ElseIf nc=9
functions←strip¨↓⍎Something,'.⎕NL 3'
Z←{(Something,'.',⍵)}¨functions
:EndIf
∇ Z←strip input
Z←(input≠' ')/input
∇ Z←get_representation Function;nc;rep
nc←⎕NC⊂Function
:If nc=3.1
rep←↓⎕CR Function
rep[1]←⊂'∇',⊃rep[1]
rep,←⊂'∇'
rep←↑rep
:Else
rep←⎕CR Function
:EndIf
Z←rep
∇ Z←ProfileData generate_cover_result(name representation);Indices;lines;functionlines;covered_lines
Indices←({name≡⍵}¨ProfileData[;1])/ProfileData[;1]
lines←ProfileData[Indices;2]
nc←⎕NC⊂name
:If 3.1=nc
functionlines←¯2+↓representation
:Else
functionlines←⊃↓representation
:EndIf
covered_lines←(⍬∘≢¨lines)/lines
Z←(nc lines functionlines covered_lines representation)
∇ Z←generate_html CoverResults;Covered;Total;Percentage;CoverageText;ColorizedCode;Timestamp;Page
Covered←⊃⊃+/{4⊃⍵}¨CoverResults
Total←⊃⊃+/{3⊃⍵}¨CoverResults
Percentage←100×Covered÷Total
CoverageText←'Coverage: ',Percentage,'% (',Covered,'/',Total,')'
ColorizedCode←⊃,/{colorize_code_by_coverage ⍵}¨CoverResults
Timestamp←generate_timestamp_text
Page←⍬
Page,←⊂⍬,'<html>'
Page,←⊂⍬,'<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>'
Page,←⊂⍬,'<style>pre cov {line-height:80%;}'
Page,←⊂⍬,'pre cov {color: green;}'
Page,←⊂⍬,'pre uncov {line-height:80%;}'
Page,←⊂⍬,'pre uncov {color:red;}</style>'
Page,←⊂⍬,CoverageText
Page,←⊂⍬,'<pre>'
Page,←ColorizedCode
Page,←⊂⍬,'</pre>'
Page,←Timestamp
Page,←⊂⍬,'</html>'
Z←Page
∇ Z←colorize_code_by_coverage CoverResult;Colors;Ends;Code
:If 3.1=⊃CoverResult
Colors←(2+3⊃CoverResult)⍴⊂'<uncov>'
Colors[1]←⊂''
Colors[Colors]←⊂''
Ends←(2+3⊃CoverResult)⍴⊂'</uncov>'
Ends[1]←⊂''
Ends[Ends]←⊂''
:Else
Colors←(3⊃CoverResult)⍴⊂'<uncov>'
Ends←(3⊃CoverResult)⍴⊂'</uncov>'
:EndIf
Colors[1+4⊃CoverResult]←⊂'<cov>'
Ends[1+4⊃CoverResult]←⊂'</cov>'
Code←↓5⊃CoverResult
Z←Colors,[1.5]Code
Z←{,(⎕UCS 13),⍵}/Z,Ends
∇ Z←generate_timestamp_text;TS;YYMMDD;HHMMSS
TS←⎕TS
YYMMDD←⊃{,'-',⍵}/3↑TS
HHMMSS←⊃{,':',⍵}/3↑3↓TS
Z←'Page generated: ',YYMMDD,'|',HHMMSS
∇ Conf write_html_to_page Page;tie;filename
filename←(⊃'cover_out'in Conf),(⊃'cover_file'in Conf)
:Trap 22
tie←filename ⎕NTIE 0
filename ⎕NERASE tie
filename ⎕NCREATE tie
:Else
tie←filename ⎕NCREATE 0
:EndTrap
Simple_array←⍕⊃,/Page
(⎕UCS'UTF-8'⎕UCS Simple_array)⎕NAPPEND tie
∇ Z←is_function Argument
Z←'_TEST'≡¯5↑Argument
∇ Z←is_list_of_functions Argument
Z←2=≡Argument
∇ Z←is_file Argument
Z←'.dyalog'≡¯7↑Argument
∇ Z←is_dir Argument;attr
:If 'Linux'≡5↑⊃'.'⎕WG'APLVersion'
Z←'yes'≡⊃⎕CMD'test -d ',Argument,' && echo yes || echo no'
:Else
'gfa'⎕NA'I kernel32|GetFileAttributes* <0t'
:If Z←¯1≠attr←gfa⊂Argument ⍝ If file exists
Z←⊃2 16attr ⍝ Return bit 4
:EndIf
:EndIf
∇ Z←test_files_in_dir Argument
:If 'Linux'≡5↑⊃'.'⎕WG'APLVersion'
Z←⎕SH'find ',Argument,' -name \*_tests.dyalog'
:Else
#.⎕CY'files'
Z←#.Files.Dir Argument,'\*_tests.dyalog'
Z←(Argument,'\')∘,¨Z
:EndIf
∇ Z←run_ut ut_data;returned;crashed;pass;crash;fail;message
(returned crashed time)←execute_function ut_data
(pass crash fail)←determine_pass_crash_or_fail returned crashed
message←determine_message pass fail crashed(2⊃ut_data)returned time
print_message_to_screen message
Z←(pass crash fail)
∇ Z←execute_function ut_data;function;t
reset_UT_globals
function←(⍕(⊃ut_data[1])),'.',⊃ut_data[2]
:Trap sac
:If 3.2≡⎕NC⊂function
t←⎕TS
Z←(⍎function,' ⍬')0
t←⎕TS-t
:Else
t←⎕TS
Z←(⍎function)0
t←⎕TS-t
:EndIf
:Else
Z←(↑⎕DM)1
:If exception≢⍬
expect←exception
Z[2]←0
t←⎕TS-t
:EndIf
:EndTrap
Z,←⊂t
∇ reset_UT_globals
expect_orig ← expect← ⎕NS⍬
exception←⍬
nexpect_orig ← nexpect← ⎕NS⍬
∇ Z←is_test FunctionName;wsIndex
wsIndex←FunctionName' '
FunctionName←(wsIndex-1)↑FunctionName
Z←'_TEST'≡¯5↑FunctionName
∇ Heading print_passed_crashed_failed(ArrayRes time)
⎕←'-----------------------------------------'
⎕←Heading
⎕←' ⍋ Passed: ',+/{1⊃⍵}¨ArrayRes
⎕←' ⍟ Crashed: ',+/{2⊃⍵}¨ArrayRes
⎕←' ⍒ Failed: ',+/{3⊃⍵}¨ArrayRes
⎕←' ○ Runtime: ',time[5],'m',time[6],'s',time[7],'ms'
determine_pass_crash_or_fail←{
r c←⍵ ⋄ 0≠c:0 1 0 ⋄ z←(0 0 1)(1 0 0)
expect_orig≢expect:(⎕IO+expect≡r)⊃z ⋄ (⎕IO+nexpect≢r)⊃z
}
∇ Z←determine_message(pass fail crashed name returned time)
:If crashed
Z←'CRASHED: 'failure_message name returned
:ElseIf pass
Z←'Passed ',time[5],'m',time[6],'s',time[7],'ms'
:Else
Z←'FAILED: 'failure_message name returned
:EndIf
∇ print_message_to_screen message
⎕←message
∇ Z←term_to_text Term;Text;Rows
Text←#.DISPLAY Term
Rows←1⊃Text
Z←(Rows 4''),Text
∇ Z←Cause failure_message(name returned);hdr;exp;expterm;got;gotterm
hdr←Cause,name
exp←'Expected'
expterm←term_to_text #.UT.expect
got←'Got'
gotterm←term_to_text returned
Z←align_and_join_message_parts hdr exp expterm got gotterm
∇ Z←align_and_join_message_parts Parts;hdr;exp;expterm;got;gotterm;R1;C1;R2;C2;W
(hdr exp expterm got gotterm)←Parts
(R1 C1)←expterm
(R2 C2)←gotterm
W←⊃⊃⌈/C1 C2(hdr)(exp)(got)
Z←(W↑hdr),[0.5](W↑exp)
Z←Z⍪(R1 W↑expterm)
Z←Z⍪(W↑got)
Z←Z⍪(R2 W↑gotterm)
∇ Z←confparam in config
Z←1↓⊃({confparam≡⊃⍵}¨config)/config
∇ Z←config has confparam
Z←/{confparam≡⊃⍵}¨config
:EndNameSpace

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<project name="WebBuild">
<!-- generate timestamps -->
<tstamp />
<!-- Debugging Macro -->
<import file="echopath.xml" />
<!-- JS build files macro -->
<import file="rhinoscript.xml" />
<!-- Component Build Files -->
<import file="setup.xml" />
<import file="clean.xml" />
<import file="copy.xml" />
<import file="file.transform.xml" />
<import file="external.tools.xml" />
<import file="rename.xml" />
<import file="js.xml" />
<import file="css.xml" />
<import file="img.xml" />
<import file="png8.xml" />
<import file="yui.xml" />
<import file="cdn.xml" />
<import file="datauri.xml" />
<import file="devlive.xml" />
<!-- This dirname is the only complete path we know for sure, everything builds off of it -->
<dirname property="dir.build" file="${ant.file.WebBuild}" />
<!-- get name for newly built folder -->
<basename property="app.name" file="${basedir}" />
<!-- read global properties file -->
<property file="${dir.build}\build.properties" />
<!-- Build Directories -->
<property name="dir.build.js" location="${dir.build}/js" />
<!-- App Directories -->
<property name="dir.app" location="${dir.result}/${app.name}" />
<property name="dir.app.temp" location="${dir.temp}/${app.name}" />
<property name="dir.app.files" location="${dir.app.temp}/${dir.files}" />
<!-- Files -->
<property name="mapping.js" location="${dir.app.temp}/${mapping.file.js}" />
<property name="mapping.css" location="${dir.app.temp}/${mapping.file.css}" />
<property name="mapping.img" location="${dir.app.temp}/${mapping.file.img}" />
<property name="mapping.swf" location="${dir.app.temp}/${mapping.file.swf}" />
<property name="mapping.fonts" location="${dir.app.temp}/${mapping.file.fonts}" />
<!-- Tool Directories -->
<property name="dir.bin" location="${dir.build}/Bin" />
<property name="dir.jar" location="${dir.bin}/jar" />
<!-- Tool Files -->
<property name="tools.compressor" location="${dir.jar}/${tools.file.compressor}" />
<property name="tools.cssembed" location="${dir.jar}/${tools.file.cssembed}" />
<property name="tools.filetransform" location="${dir.jar}/${tools.file.filetransform}" />
<property name="tools.optipng" location="${dir.bin}/${tools.file.optipng}" />
<property name="tools.jpegtran" location="${dir.bin}/${tools.file.jpegtran}" />
<!-- BUILD TARGETS -->
<!-- low level utility build targets -->
<!-- Build the tools -->
<target name="-setup.build.tools"
depends="-define.filetransform, -define.cssembed, -define.yuicompressor, -define.jsclasspath"
/>
<!-- set up filesystem properties -->
<target
name="-setup"
depends="-setup.mode, -setup.conditions, -setup.js, -setup.css, -setup.swf, -setup.img, -setup.fonts, -setup.yui"
/>
<!-- utility-ish targets -->
<target name="copy" depends="clean, tools, -copy" />
<target name="tools" depends="-setup.build.tools" />
<target name="finalize" depends="copy, -finalize" />
<target name="-prepare" depends="copy, -setup" />
<!-- individual component build targets (empty descriptions are to make sure they show in "ant -p") -->
<target name="devlive" depends="-prepare, -devlive" description="" />
<target name="js" depends="-prepare, -js" description="" />
<target name="css" depends="-prepare, -css" description="" />
<target name="rename" depends="-prepare, -rename" description="" />
<target name="yui" depends="-prepare, rename, -yui" description="" />
<target name="cdn" depends="-prepare, -cdn" description="" />
<!-- high level build targets (Excluding of images is on purpose here, it's slow) -->
<target name="core"
depends="devlive, js, css, cdn, rename, yui, -js.inline"
description="Core build work"
/>
<target name="prod"
depends="core, finalize"
description="Full Production Build"
/>
<!-- debug target -->
<target name="debug" depends="-setup">
<echoproperties/>
</target>
</project>

View File

@@ -0,0 +1 @@
ant.xml

View File

@@ -0,0 +1,66 @@
ORG 0000h
SJMP START
ORG 0003h
LCALL INT0_ISR
RETI
ORG 000Bh
LCALL T0_ISR
RETI
ORG 0013h
LCALL INT1_ISR
RETI
ORG 001Bh
LCALL T1_ISR
RETI
ORG 0023h
LCALL UART_ISR
RETI
ORG 0030h
START:
MOV A,#11111110b
SETB IT0 ; Set External Interrupt 0 to be falling edge triggered
SETB EX0 ; Enable External Interrut 0
SETB EA ; Enable Interrupt
LEFT:
CJNE A,#01111111b,LOOP1
JMP RIGHT
LOOP1:
MOV P1,A
RL A
LCALL DELAY
SJMP LEFT
RIGHT:
CJNE A,#11111110b,LOOP2
JMP LEFT
LOOP2:
MOV P1,A
RR A
LCALL DELAY
SJMP RIGHT
INT0_ISR:
MOV R1,#3
FLASH:
MOV P1,#00h
LCALL DELAY
MOV P1,#0FFh
LCALL DELAY
DJNZ R1,FLASH
RET
T0_ISR:
RET
INT1_ISR:
RET
T1_ISR:
RET
UART_ISR:
RET
DELAY: MOV R5,#20 ;R5*20 mS
D1: MOV R6,#40
D2: MOV R7,#249
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
END

86
samples/C++/16F88.h Normal file
View File

@@ -0,0 +1,86 @@
/*
* This file is part of PIC
* Copyright © 2012 Rachel Mant (dx-mon@users.sourceforge.net)
*
* PIC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PIC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
enum PIC16F88Instruction
{
ADDWF,
ANDWF,
CLRF,
CLRW,
COMF,
DECF,
DECFSZ,
INCF,
INCFSZ,
IORWF,
MOVF,
MOVWF,
NOP,
RLF,
RRF,
SUBWF,
SWAPF,
XORWF,
BCF,
BSF,
BTFSC,
BTFSS,
ADDLW,
ANDLW,
CALL,
CLRWDT,
GOTO,
IORLW,
MOVLW,
RETFIE,
RETLW,
RETURN,
SLEEP,
SUBLW,
XORLW
};
class PIC16F88
{
public:
PIC16F88(ROM *ProgramMemory);
void Step();
private:
uint8_t q;
bool nextIsNop, trapped;
Memory *memory;
ROM *program;
Stack<uint16_t, 8> *CallStack;
Register<uint16_t> *PC;
Register<> *WREG, *PCL, *STATUS, *PCLATCH;
PIC16F88Instruction inst;
uint16_t instrWord;
private:
void DecodeInstruction();
void ProcessInstruction();
uint8_t GetBank();
uint8_t GetMemoryContents(uint8_t partialAddress);
void SetMemoryContents(uint8_t partialAddress, uint8_t newVal);
void CheckZero(uint8_t value);
void StoreValue(uint8_t value, bool updateZero);
uint8_t SetCarry(bool val);
uint16_t GetPCHFinalBits();
};

32
samples/C++/Memory16F88.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* This file is part of PIC
* Copyright © 2012 Rachel Mant (dx-mon@users.sourceforge.net)
*
* PIC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PIC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Memory.h"
class Memory16F88 : public Memory
{
private:
uint8_t memory[512];
std::map<uint32_t, MemoryLocation *> memoryMap;
public:
Memory16F88();
uint8_t Dereference(uint8_t bank, uint8_t partialAddress);
uint8_t *Reference(uint8_t bank, uint8_t partialAddress);
uint8_t *operator [](uint32_t ref);
};

View File

@@ -0,0 +1,76 @@
/*
* This file is part of IRCBot
* Copyright © 2014 Rachel Mant (dx-mon@users.sourceforge.net)
*
* IRCBot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* IRCBot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __THREADED_QUEUE_H__
#define __THREADED_QUEUE_H__
#include <pthread.h>
#include <queue>
template<class T>
class ThreadedQueue : public std::queue<T>
{
private:
pthread_mutex_t queueMutex;
pthread_cond_t queueCond;
public:
ThreadedQueue()
{
pthread_mutexattr_t mutexAttrs;
pthread_condattr_t condAttrs;
pthread_mutexattr_init(&mutexAttrs);
pthread_mutexattr_settype(&mutexAttrs, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&queueMutex, &mutexAttrs);
pthread_mutexattr_destroy(&mutexAttrs);
pthread_condattr_init(&condAttrs);
pthread_condattr_setpshared(&condAttrs, PTHREAD_PROCESS_PRIVATE);
pthread_cond_init(&queueCond, &condAttrs);
pthread_condattr_destroy(&condAttrs);
}
~ThreadedQueue()
{
pthread_cond_destroy(&queueCond);
pthread_mutex_destroy(&queueMutex);
}
void waitItems()
{
pthread_mutex_lock(&queueMutex);
pthread_cond_wait(&queueCond, &queueMutex);
pthread_mutex_unlock(&queueMutex);
}
void signalItems()
{
pthread_mutex_lock(&queueMutex);
pthread_cond_broadcast(&queueCond);
pthread_mutex_unlock(&queueMutex);
}
void push(T item)
{
std::queue<T>::push(item);
signalItems();
}
};
#endif /*__THREADED_QUEUE_H__*/

10
samples/C++/bar.hh Normal file
View File

@@ -0,0 +1,10 @@
class Bar
{
protected:
char *name;
public:
void hello();
}

145
samples/C/2D.C Normal file
View File

@@ -0,0 +1,145 @@
#include "2D.h"
#include <math.h>
void set_vgabasemem(void)
{
ULONG vgabase;
SELECTOR tmp;
asm mov [tmp], ds
dpmi_get_sel_base(&vgabase, tmp);
vgabasemem = (char *)(-vgabase + 0xa0000);
}
void drw_chdis(int mode) // change the display!
{
regs.b.ah = 0x00; // seet theh display moode
regs.b.al = mode; // change it to the mode like innit
regs.h.flags = 0x72;// Set the dingoes kidneys out of FLAGS eh?
regs.h.ss = 0; // Like, totally set the stack segment
regs.h.sp = 0; // Set tha stack pointaaaaahhhhh!!!
dpmi_simulate_real_interrupt(0x10, &regs);
}
void drw_pix(int x, int y, enum COLORS col)
{
*VGAPIX(x, y) = col;
}
void drw_line(int x0, int y0, int x1, int y1, enum COLORS col)
{
// Going for the optimized version of bresenham's line algo.
int stp = (abs(y0 - y1) > abs(x0 - x1));
int tmp, dx, dy, err, yi, i, j; // yi = y excrement
if (stp) {
// swappity swap
tmp = y0;
y0 = x0;
x0 = tmp;
tmp = y1;
y1 = x1;
x1 = tmp;
}
// AAAAND NOW WE MUST DO ZEES AGAIN :(
// I'm sure there was a func somewhere that does this? :P
if (x0 > x1) {
tmp = x0;
x0 = x1;
x1 = tmp;
tmp = y0;
y0 = y1;
y1 = tmp;
}
dx = (x1 - x0);
dy = (abs(y1 - y0));
err = (dx / 2);
if (y0 < y1)
yi = 1;
else
yi = -1;
j = y0;
for (i = x0; i < x1; i++)
{
if (stp)
*VGAPIX(j, i) = col;
else
*VGAPIX(i, j) = col;
err -= dy;
if (err < 0) {
j += yi;
err += dx;
}
}
}
void drw_rectl(int x, int y, int w, int h, enum COLORS col)
{
drw_line(x, y, x+w, y, col);
drw_line(x+w, y, x+w, y+h, col);
drw_line(x, y, x, y+h, col);
drw_line(x, y+h, x+w+1, y+h, col);
}
void drw_rectf(int x, int y, int w, int h, enum COLORS col)
{
int i, j;
for (j = y; j < x+h; j++) {
for (i = x; i < y+w; i++) {
*VGAPIX(i, j) = col;
}
}
}
void drw_circl(int x, int y, int rad, enum COLORS col)
{
int mang, i; // max angle, haha
int px, py;
mang = 360; // Yeah yeah I'll switch to rad later
for (i = 0; i <= mang; i++)
{
px = cos(i)*rad + x; // + px; // causes some really cools effects! :D
py = sin(i)*rad + y; // + py;
*VGAPIX(px, py) = col;
}
}
void drw_tex(int x, int y, int w, int h, enum COLORS tex[])
{ // i*w+j
int i, j;
for (i = 0; i < w; i++)
{
for (j = 0; j < h; j++)
{
*VGAPIX(x+i, y+j) = tex[j*w+i];
}
}
}
void 2D_init(void)
{
set_vgabasemem();
drw_chdis(0x13);
}
void 2D_exit(void)
{
drw_chdis(3);
}
/*
int main()
{
set_vgabasemem();
drw_chdis(0x13);
while(!kbhit()) {
if ((getch()) == 0x1b) // escape
break;
}
drw_chdis(3);
return 0;
}
*/

29
samples/C/2D.H Normal file
View File

@@ -0,0 +1,29 @@
#ifndef __2DGFX
#define __2DGFX
// Includes
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <dpmi.h>
// Defines
#define VGAPIX(x,y) (vgabasemem + (x) + (y) * 320)
// Variables
char * vgabasemem;
DPMI_REGS regs;
// Drawing functions:
//void setvgabasemem(void);
void drw_chdis(int mode); // draw_func_change_display
void drw_pix(int x, int y, enum COLORS col);
void drw_line(int x0, int y0, int x1, int y1, enum COLORS col);
void drw_rectl(int x, int y, int w, int h, enum COLORS col);
void drw_rectf(int x, int y, int w, int h, enum COLORS col);
void drw_cirl(int x, int y, int rad, enum COLORS col);
void drw_tex(int x, int y, int w, int h, enum COLORS tex[]);
void 2D_init(void);
void 2D_exit(void);
#endif

93
samples/C/ArrowLeft.h Normal file
View File

@@ -0,0 +1,93 @@
/*
* This file is part of GTK++ (libGTK++)
* Copyright © 2012 Rachel Mant (dx-mon@users.sourceforge.net)
*
* GTK++ is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GTK++ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* GdkPixbuf RGBA C-Source image dump */
#ifdef __SUNPRO_C
#pragma align 4 (ArrowLeft)
#endif
#ifdef __GNUC__
static const uint8_t ArrowLeft[] __attribute__ ((__aligned__ (4))) =
#else
static const uint8_t ArrowLeft[] =
#endif
{ ""
/* Pixbuf magic (0x47646b50) */
"GdkP"
/* length: header (24) + pixel_data (1600) */
"\0\0\6X"
/* pixdata_type (0x1010002) */
"\1\1\0\2"
/* rowstride (80) */
"\0\0\0P"
/* width (20) */
"\0\0\0\24"
/* height (20) */
"\0\0\0\24"
/* pixel_data: */
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377"
"\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
"\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0"
"\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0"};

903
samples/C/GLKMatrix4.h Normal file
View File

@@ -0,0 +1,903 @@
//
// GLKMatrix4.h
// GLKit
//
// Copyright (c) 2011, Apple Inc. All rights reserved.
//
#ifndef __GLK_MATRIX_4_H
#define __GLK_MATRIX_4_H
#include <stddef.h>
#include <stdbool.h>
#include <math.h>
#if defined(__ARM_NEON__)
#include <arm_neon.h>
#endif
#include <GLKit/GLKMathTypes.h>
#include <GLKit/GLKVector3.h>
#include <GLKit/GLKVector4.h>
#include <GLKit/GLKQuaternion.h>
#ifdef __cplusplus
extern "C" {
#endif
#pragma mark -
#pragma mark Prototypes
#pragma mark -
extern const GLKMatrix4 GLKMatrix4Identity;
/*
m30, m31, and m32 correspond to the translation values tx, ty, tz, respectively.
*/
static __inline__ GLKMatrix4 GLKMatrix4Make(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33);
/*
m03, m13, and m23 correspond to the translation values tx, ty, tz, respectively.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeAndTranspose(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33);
/*
m[12], m[13], and m[14] correspond to the translation values tx, ty, and tz, respectively.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeWithArray(float values[16]);
/*
m[3], m[7], and m[11] correspond to the translation values tx, ty, and tz, respectively.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeWithArrayAndTranspose(float values[16]);
/*
row0, row1, and row2's last component should correspond to the translation values tx, ty, and tz, respectively.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeWithRows(GLKVector4 row0,
GLKVector4 row1,
GLKVector4 row2,
GLKVector4 row3);
/*
column3's first three components should correspond to the translation values tx, ty, and tz.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeWithColumns(GLKVector4 column0,
GLKVector4 column1,
GLKVector4 column2,
GLKVector4 column3);
/*
The quaternion will be normalized before conversion.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeWithQuaternion(GLKQuaternion quaternion);
static __inline__ GLKMatrix4 GLKMatrix4MakeTranslation(float tx, float ty, float tz);
static __inline__ GLKMatrix4 GLKMatrix4MakeScale(float sx, float sy, float sz);
static __inline__ GLKMatrix4 GLKMatrix4MakeRotation(float radians, float x, float y, float z);
static __inline__ GLKMatrix4 GLKMatrix4MakeXRotation(float radians);
static __inline__ GLKMatrix4 GLKMatrix4MakeYRotation(float radians);
static __inline__ GLKMatrix4 GLKMatrix4MakeZRotation(float radians);
/*
Equivalent to gluPerspective.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakePerspective(float fovyRadians, float aspect, float nearZ, float farZ);
/*
Equivalent to glFrustum.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeFrustum(float left, float right,
float bottom, float top,
float nearZ, float farZ);
/*
Equivalent to glOrtho.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeOrtho(float left, float right,
float bottom, float top,
float nearZ, float farZ);
/*
Equivalent to gluLookAt.
*/
static __inline__ GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,
float centerX, float centerY, float centerZ,
float upX, float upY, float upZ);
/*
Returns the upper left 3x3 portion of the 4x4 matrix.
*/
static __inline__ GLKMatrix3 GLKMatrix4GetMatrix3(GLKMatrix4 matrix);
/*
Returns the upper left 2x2 portion of the 4x4 matrix.
*/
static __inline__ GLKMatrix2 GLKMatrix4GetMatrix2(GLKMatrix4 matrix);
/*
GLKMatrix4GetRow returns vectors for rows 0, 1, and 2 whose last component will be the translation value tx, ty, and tz, respectively.
Valid row values range from 0 to 3, inclusive.
*/
static __inline__ GLKVector4 GLKMatrix4GetRow(GLKMatrix4 matrix, int row);
/*
GLKMatrix4GetColumn returns a vector for column 3 whose first three components will be the translation values tx, ty, and tz.
Valid column values range from 0 to 3, inclusive.
*/
static __inline__ GLKVector4 GLKMatrix4GetColumn(GLKMatrix4 matrix, int column);
/*
GLKMatrix4SetRow expects that the vector for row 0, 1, and 2 will have a translation value as its last component.
Valid row values range from 0 to 3, inclusive.
*/
static __inline__ GLKMatrix4 GLKMatrix4SetRow(GLKMatrix4 matrix, int row, GLKVector4 vector);
/*
GLKMatrix4SetColumn expects that the vector for column 3 will contain the translation values tx, ty, and tz as its first three components, respectively.
Valid column values range from 0 to 3, inclusive.
*/
static __inline__ GLKMatrix4 GLKMatrix4SetColumn(GLKMatrix4 matrix, int column, GLKVector4 vector);
static __inline__ GLKMatrix4 GLKMatrix4Transpose(GLKMatrix4 matrix);
GLKMatrix4 GLKMatrix4Invert(GLKMatrix4 matrix, bool *isInvertible);
GLKMatrix4 GLKMatrix4InvertAndTranspose(GLKMatrix4 matrix, bool *isInvertible);
static __inline__ GLKMatrix4 GLKMatrix4Multiply(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight);
static __inline__ GLKMatrix4 GLKMatrix4Add(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight);
static __inline__ GLKMatrix4 GLKMatrix4Subtract(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight);
static __inline__ GLKMatrix4 GLKMatrix4Translate(GLKMatrix4 matrix, float tx, float ty, float tz);
static __inline__ GLKMatrix4 GLKMatrix4TranslateWithVector3(GLKMatrix4 matrix, GLKVector3 translationVector);
/*
The last component of the GLKVector4, translationVector, is ignored.
*/
static __inline__ GLKMatrix4 GLKMatrix4TranslateWithVector4(GLKMatrix4 matrix, GLKVector4 translationVector);
static __inline__ GLKMatrix4 GLKMatrix4Scale(GLKMatrix4 matrix, float sx, float sy, float sz);
static __inline__ GLKMatrix4 GLKMatrix4ScaleWithVector3(GLKMatrix4 matrix, GLKVector3 scaleVector);
/*
The last component of the GLKVector4, scaleVector, is ignored.
*/
static __inline__ GLKMatrix4 GLKMatrix4ScaleWithVector4(GLKMatrix4 matrix, GLKVector4 scaleVector);
static __inline__ GLKMatrix4 GLKMatrix4Rotate(GLKMatrix4 matrix, float radians, float x, float y, float z);
static __inline__ GLKMatrix4 GLKMatrix4RotateWithVector3(GLKMatrix4 matrix, float radians, GLKVector3 axisVector);
/*
The last component of the GLKVector4, axisVector, is ignored.
*/
static __inline__ GLKMatrix4 GLKMatrix4RotateWithVector4(GLKMatrix4 matrix, float radians, GLKVector4 axisVector);
static __inline__ GLKMatrix4 GLKMatrix4RotateX(GLKMatrix4 matrix, float radians);
static __inline__ GLKMatrix4 GLKMatrix4RotateY(GLKMatrix4 matrix, float radians);
static __inline__ GLKMatrix4 GLKMatrix4RotateZ(GLKMatrix4 matrix, float radians);
/*
Assumes 0 in the w component.
*/
static __inline__ GLKVector3 GLKMatrix4MultiplyVector3(GLKMatrix4 matrixLeft, GLKVector3 vectorRight);
/*
Assumes 1 in the w component.
*/
static __inline__ GLKVector3 GLKMatrix4MultiplyVector3WithTranslation(GLKMatrix4 matrixLeft, GLKVector3 vectorRight);
/*
Assumes 1 in the w component and divides the resulting vector by w before returning.
*/
static __inline__ GLKVector3 GLKMatrix4MultiplyAndProjectVector3(GLKMatrix4 matrixLeft, GLKVector3 vectorRight);
/*
Assumes 0 in the w component.
*/
static __inline__ void GLKMatrix4MultiplyVector3Array(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount);
/*
Assumes 1 in the w component.
*/
static __inline__ void GLKMatrix4MultiplyVector3ArrayWithTranslation(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount);
/*
Assumes 1 in the w component and divides the resulting vector by w before returning.
*/
static __inline__ void GLKMatrix4MultiplyAndProjectVector3Array(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount);
static __inline__ GLKVector4 GLKMatrix4MultiplyVector4(GLKMatrix4 matrixLeft, GLKVector4 vectorRight);
static __inline__ void GLKMatrix4MultiplyVector4Array(GLKMatrix4 matrix, GLKVector4 *vectors, size_t vectorCount);
#pragma mark -
#pragma mark Implementations
#pragma mark -
static __inline__ GLKMatrix4 GLKMatrix4Make(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33)
{
GLKMatrix4 m = { m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23,
m30, m31, m32, m33 };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeAndTranspose(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33)
{
GLKMatrix4 m = { m00, m10, m20, m30,
m01, m11, m21, m31,
m02, m12, m22, m32,
m03, m13, m23, m33 };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeWithArray(float values[16])
{
GLKMatrix4 m = { values[0], values[1], values[2], values[3],
values[4], values[5], values[6], values[7],
values[8], values[9], values[10], values[11],
values[12], values[13], values[14], values[15] };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeWithArrayAndTranspose(float values[16])
{
#if defined(__ARM_NEON__)
float32x4x4_t m = vld4q_f32(values);
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m = { values[0], values[4], values[8], values[12],
values[1], values[5], values[9], values[13],
values[2], values[6], values[10], values[14],
values[3], values[7], values[11], values[15] };
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4MakeWithRows(GLKVector4 row0,
GLKVector4 row1,
GLKVector4 row2,
GLKVector4 row3)
{
GLKMatrix4 m = { row0.v[0], row1.v[0], row2.v[0], row3.v[0],
row0.v[1], row1.v[1], row2.v[1], row3.v[1],
row0.v[2], row1.v[2], row2.v[2], row3.v[2],
row0.v[3], row1.v[3], row2.v[3], row3.v[3] };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeWithColumns(GLKVector4 column0,
GLKVector4 column1,
GLKVector4 column2,
GLKVector4 column3)
{
#if defined(__ARM_NEON__)
float32x4x4_t m;
m.val[0] = vld1q_f32(column0.v);
m.val[1] = vld1q_f32(column1.v);
m.val[2] = vld1q_f32(column2.v);
m.val[3] = vld1q_f32(column3.v);
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m = { column0.v[0], column0.v[1], column0.v[2], column0.v[3],
column1.v[0], column1.v[1], column1.v[2], column1.v[3],
column2.v[0], column2.v[1], column2.v[2], column2.v[3],
column3.v[0], column3.v[1], column3.v[2], column3.v[3] };
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4MakeWithQuaternion(GLKQuaternion quaternion)
{
quaternion = GLKQuaternionNormalize(quaternion);
float x = quaternion.q[0];
float y = quaternion.q[1];
float z = quaternion.q[2];
float w = quaternion.q[3];
float _2x = x + x;
float _2y = y + y;
float _2z = z + z;
float _2w = w + w;
GLKMatrix4 m = { 1.0f - _2y * y - _2z * z,
_2x * y + _2w * z,
_2x * z - _2w * y,
0.0f,
_2x * y - _2w * z,
1.0f - _2x * x - _2z * z,
_2y * z + _2w * x,
0.0f,
_2x * z + _2w * y,
_2y * z - _2w * x,
1.0f - _2x * x - _2y * y,
0.0f,
0.0f,
0.0f,
0.0f,
1.0f };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeTranslation(float tx, float ty, float tz)
{
GLKMatrix4 m = GLKMatrix4Identity;
m.m[12] = tx;
m.m[13] = ty;
m.m[14] = tz;
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeScale(float sx, float sy, float sz)
{
GLKMatrix4 m = GLKMatrix4Identity;
m.m[0] = sx;
m.m[5] = sy;
m.m[10] = sz;
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeRotation(float radians, float x, float y, float z)
{
GLKVector3 v = GLKVector3Normalize(GLKVector3Make(x, y, z));
float cos = cosf(radians);
float cosp = 1.0f - cos;
float sin = sinf(radians);
GLKMatrix4 m = { cos + cosp * v.v[0] * v.v[0],
cosp * v.v[0] * v.v[1] + v.v[2] * sin,
cosp * v.v[0] * v.v[2] - v.v[1] * sin,
0.0f,
cosp * v.v[0] * v.v[1] - v.v[2] * sin,
cos + cosp * v.v[1] * v.v[1],
cosp * v.v[1] * v.v[2] + v.v[0] * sin,
0.0f,
cosp * v.v[0] * v.v[2] + v.v[1] * sin,
cosp * v.v[1] * v.v[2] - v.v[0] * sin,
cos + cosp * v.v[2] * v.v[2],
0.0f,
0.0f,
0.0f,
0.0f,
1.0f };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeXRotation(float radians)
{
float cos = cosf(radians);
float sin = sinf(radians);
GLKMatrix4 m = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, cos, sin, 0.0f,
0.0f, -sin, cos, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeYRotation(float radians)
{
float cos = cosf(radians);
float sin = sinf(radians);
GLKMatrix4 m = { cos, 0.0f, -sin, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
sin, 0.0f, cos, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeZRotation(float radians)
{
float cos = cosf(radians);
float sin = sinf(radians);
GLKMatrix4 m = { cos, sin, 0.0f, 0.0f,
-sin, cos, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakePerspective(float fovyRadians, float aspect, float nearZ, float farZ)
{
float cotan = 1.0f / tanf(fovyRadians / 2.0f);
GLKMatrix4 m = { cotan / aspect, 0.0f, 0.0f, 0.0f,
0.0f, cotan, 0.0f, 0.0f,
0.0f, 0.0f, (farZ + nearZ) / (nearZ - farZ), -1.0f,
0.0f, 0.0f, (2.0f * farZ * nearZ) / (nearZ - farZ), 0.0f };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeFrustum(float left, float right,
float bottom, float top,
float nearZ, float farZ)
{
float ral = right + left;
float rsl = right - left;
float tsb = top - bottom;
float tab = top + bottom;
float fan = farZ + nearZ;
float fsn = farZ - nearZ;
GLKMatrix4 m = { 2.0f * nearZ / rsl, 0.0f, 0.0f, 0.0f,
0.0f, 2.0f * nearZ / tsb, 0.0f, 0.0f,
ral / rsl, tab / tsb, -fan / fsn, -1.0f,
0.0f, 0.0f, (-2.0f * farZ * nearZ) / fsn, 0.0f };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeOrtho(float left, float right,
float bottom, float top,
float nearZ, float farZ)
{
float ral = right + left;
float rsl = right - left;
float tab = top + bottom;
float tsb = top - bottom;
float fan = farZ + nearZ;
float fsn = farZ - nearZ;
GLKMatrix4 m = { 2.0f / rsl, 0.0f, 0.0f, 0.0f,
0.0f, 2.0f / tsb, 0.0f, 0.0f,
0.0f, 0.0f, -2.0f / fsn, 0.0f,
-ral / rsl, -tab / tsb, -fan / fsn, 1.0f };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,
float centerX, float centerY, float centerZ,
float upX, float upY, float upZ)
{
GLKVector3 ev = { eyeX, eyeY, eyeZ };
GLKVector3 cv = { centerX, centerY, centerZ };
GLKVector3 uv = { upX, upY, upZ };
GLKVector3 n = GLKVector3Normalize(GLKVector3Add(ev, GLKVector3Negate(cv)));
GLKVector3 u = GLKVector3Normalize(GLKVector3CrossProduct(uv, n));
GLKVector3 v = GLKVector3CrossProduct(n, u);
GLKMatrix4 m = { u.v[0], v.v[0], n.v[0], 0.0f,
u.v[1], v.v[1], n.v[1], 0.0f,
u.v[2], v.v[2], n.v[2], 0.0f,
GLKVector3DotProduct(GLKVector3Negate(u), ev),
GLKVector3DotProduct(GLKVector3Negate(v), ev),
GLKVector3DotProduct(GLKVector3Negate(n), ev),
1.0f };
return m;
}
static __inline__ GLKMatrix3 GLKMatrix4GetMatrix3(GLKMatrix4 matrix)
{
GLKMatrix3 m = { matrix.m[0], matrix.m[1], matrix.m[2],
matrix.m[4], matrix.m[5], matrix.m[6],
matrix.m[8], matrix.m[9], matrix.m[10] };
return m;
}
static __inline__ GLKMatrix2 GLKMatrix4GetMatrix2(GLKMatrix4 matrix)
{
GLKMatrix2 m = { matrix.m[0], matrix.m[1],
matrix.m[4], matrix.m[5] };
return m;
}
static __inline__ GLKVector4 GLKMatrix4GetRow(GLKMatrix4 matrix, int row)
{
GLKVector4 v = { matrix.m[row], matrix.m[4 + row], matrix.m[8 + row], matrix.m[12 + row] };
return v;
}
static __inline__ GLKVector4 GLKMatrix4GetColumn(GLKMatrix4 matrix, int column)
{
#if defined(__ARM_NEON__)
float32x4_t v = vld1q_f32(&(matrix.m[column * 4]));
return *(GLKVector4 *)&v;
#else
GLKVector4 v = { matrix.m[column * 4 + 0], matrix.m[column * 4 + 1], matrix.m[column * 4 + 2], matrix.m[column * 4 + 3] };
return v;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4SetRow(GLKMatrix4 matrix, int row, GLKVector4 vector)
{
matrix.m[row] = vector.v[0];
matrix.m[row + 4] = vector.v[1];
matrix.m[row + 8] = vector.v[2];
matrix.m[row + 12] = vector.v[3];
return matrix;
}
static __inline__ GLKMatrix4 GLKMatrix4SetColumn(GLKMatrix4 matrix, int column, GLKVector4 vector)
{
#if defined(__ARM_NEON__)
float *dst = &(matrix.m[column * 4]);
vst1q_f32(dst, vld1q_f32(vector.v));
return matrix;
#else
matrix.m[column * 4 + 0] = vector.v[0];
matrix.m[column * 4 + 1] = vector.v[1];
matrix.m[column * 4 + 2] = vector.v[2];
matrix.m[column * 4 + 3] = vector.v[3];
return matrix;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4Transpose(GLKMatrix4 matrix)
{
#if defined(__ARM_NEON__)
float32x4x4_t m = vld4q_f32(matrix.m);
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m = { matrix.m[0], matrix.m[4], matrix.m[8], matrix.m[12],
matrix.m[1], matrix.m[5], matrix.m[9], matrix.m[13],
matrix.m[2], matrix.m[6], matrix.m[10], matrix.m[14],
matrix.m[3], matrix.m[7], matrix.m[11], matrix.m[15] };
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4Multiply(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight)
{
#if defined(__ARM_NEON__)
float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft;
float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight;
float32x4x4_t m;
m.val[0] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[0], 0));
m.val[1] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[1], 0));
m.val[2] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[2], 0));
m.val[3] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[3], 0));
m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[0], 1));
m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[1], 1));
m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[2], 1));
m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[3], 1));
m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[0], 2));
m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[1], 2));
m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[2], 2));
m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[3], 2));
m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[0], 3));
m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[1], 3));
m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[2], 3));
m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[3], 3));
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m;
m.m[0] = matrixLeft.m[0] * matrixRight.m[0] + matrixLeft.m[4] * matrixRight.m[1] + matrixLeft.m[8] * matrixRight.m[2] + matrixLeft.m[12] * matrixRight.m[3];
m.m[4] = matrixLeft.m[0] * matrixRight.m[4] + matrixLeft.m[4] * matrixRight.m[5] + matrixLeft.m[8] * matrixRight.m[6] + matrixLeft.m[12] * matrixRight.m[7];
m.m[8] = matrixLeft.m[0] * matrixRight.m[8] + matrixLeft.m[4] * matrixRight.m[9] + matrixLeft.m[8] * matrixRight.m[10] + matrixLeft.m[12] * matrixRight.m[11];
m.m[12] = matrixLeft.m[0] * matrixRight.m[12] + matrixLeft.m[4] * matrixRight.m[13] + matrixLeft.m[8] * matrixRight.m[14] + matrixLeft.m[12] * matrixRight.m[15];
m.m[1] = matrixLeft.m[1] * matrixRight.m[0] + matrixLeft.m[5] * matrixRight.m[1] + matrixLeft.m[9] * matrixRight.m[2] + matrixLeft.m[13] * matrixRight.m[3];
m.m[5] = matrixLeft.m[1] * matrixRight.m[4] + matrixLeft.m[5] * matrixRight.m[5] + matrixLeft.m[9] * matrixRight.m[6] + matrixLeft.m[13] * matrixRight.m[7];
m.m[9] = matrixLeft.m[1] * matrixRight.m[8] + matrixLeft.m[5] * matrixRight.m[9] + matrixLeft.m[9] * matrixRight.m[10] + matrixLeft.m[13] * matrixRight.m[11];
m.m[13] = matrixLeft.m[1] * matrixRight.m[12] + matrixLeft.m[5] * matrixRight.m[13] + matrixLeft.m[9] * matrixRight.m[14] + matrixLeft.m[13] * matrixRight.m[15];
m.m[2] = matrixLeft.m[2] * matrixRight.m[0] + matrixLeft.m[6] * matrixRight.m[1] + matrixLeft.m[10] * matrixRight.m[2] + matrixLeft.m[14] * matrixRight.m[3];
m.m[6] = matrixLeft.m[2] * matrixRight.m[4] + matrixLeft.m[6] * matrixRight.m[5] + matrixLeft.m[10] * matrixRight.m[6] + matrixLeft.m[14] * matrixRight.m[7];
m.m[10] = matrixLeft.m[2] * matrixRight.m[8] + matrixLeft.m[6] * matrixRight.m[9] + matrixLeft.m[10] * matrixRight.m[10] + matrixLeft.m[14] * matrixRight.m[11];
m.m[14] = matrixLeft.m[2] * matrixRight.m[12] + matrixLeft.m[6] * matrixRight.m[13] + matrixLeft.m[10] * matrixRight.m[14] + matrixLeft.m[14] * matrixRight.m[15];
m.m[3] = matrixLeft.m[3] * matrixRight.m[0] + matrixLeft.m[7] * matrixRight.m[1] + matrixLeft.m[11] * matrixRight.m[2] + matrixLeft.m[15] * matrixRight.m[3];
m.m[7] = matrixLeft.m[3] * matrixRight.m[4] + matrixLeft.m[7] * matrixRight.m[5] + matrixLeft.m[11] * matrixRight.m[6] + matrixLeft.m[15] * matrixRight.m[7];
m.m[11] = matrixLeft.m[3] * matrixRight.m[8] + matrixLeft.m[7] * matrixRight.m[9] + matrixLeft.m[11] * matrixRight.m[10] + matrixLeft.m[15] * matrixRight.m[11];
m.m[15] = matrixLeft.m[3] * matrixRight.m[12] + matrixLeft.m[7] * matrixRight.m[13] + matrixLeft.m[11] * matrixRight.m[14] + matrixLeft.m[15] * matrixRight.m[15];
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4Add(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight)
{
#if defined(__ARM_NEON__)
float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft;
float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight;
float32x4x4_t m;
m.val[0] = vaddq_f32(iMatrixLeft.val[0], iMatrixRight.val[0]);
m.val[1] = vaddq_f32(iMatrixLeft.val[1], iMatrixRight.val[1]);
m.val[2] = vaddq_f32(iMatrixLeft.val[2], iMatrixRight.val[2]);
m.val[3] = vaddq_f32(iMatrixLeft.val[3], iMatrixRight.val[3]);
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m;
m.m[0] = matrixLeft.m[0] + matrixRight.m[0];
m.m[1] = matrixLeft.m[1] + matrixRight.m[1];
m.m[2] = matrixLeft.m[2] + matrixRight.m[2];
m.m[3] = matrixLeft.m[3] + matrixRight.m[3];
m.m[4] = matrixLeft.m[4] + matrixRight.m[4];
m.m[5] = matrixLeft.m[5] + matrixRight.m[5];
m.m[6] = matrixLeft.m[6] + matrixRight.m[6];
m.m[7] = matrixLeft.m[7] + matrixRight.m[7];
m.m[8] = matrixLeft.m[8] + matrixRight.m[8];
m.m[9] = matrixLeft.m[9] + matrixRight.m[9];
m.m[10] = matrixLeft.m[10] + matrixRight.m[10];
m.m[11] = matrixLeft.m[11] + matrixRight.m[11];
m.m[12] = matrixLeft.m[12] + matrixRight.m[12];
m.m[13] = matrixLeft.m[13] + matrixRight.m[13];
m.m[14] = matrixLeft.m[14] + matrixRight.m[14];
m.m[15] = matrixLeft.m[15] + matrixRight.m[15];
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4Subtract(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight)
{
#if defined(__ARM_NEON__)
float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft;
float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight;
float32x4x4_t m;
m.val[0] = vsubq_f32(iMatrixLeft.val[0], iMatrixRight.val[0]);
m.val[1] = vsubq_f32(iMatrixLeft.val[1], iMatrixRight.val[1]);
m.val[2] = vsubq_f32(iMatrixLeft.val[2], iMatrixRight.val[2]);
m.val[3] = vsubq_f32(iMatrixLeft.val[3], iMatrixRight.val[3]);
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m;
m.m[0] = matrixLeft.m[0] - matrixRight.m[0];
m.m[1] = matrixLeft.m[1] - matrixRight.m[1];
m.m[2] = matrixLeft.m[2] - matrixRight.m[2];
m.m[3] = matrixLeft.m[3] - matrixRight.m[3];
m.m[4] = matrixLeft.m[4] - matrixRight.m[4];
m.m[5] = matrixLeft.m[5] - matrixRight.m[5];
m.m[6] = matrixLeft.m[6] - matrixRight.m[6];
m.m[7] = matrixLeft.m[7] - matrixRight.m[7];
m.m[8] = matrixLeft.m[8] - matrixRight.m[8];
m.m[9] = matrixLeft.m[9] - matrixRight.m[9];
m.m[10] = matrixLeft.m[10] - matrixRight.m[10];
m.m[11] = matrixLeft.m[11] - matrixRight.m[11];
m.m[12] = matrixLeft.m[12] - matrixRight.m[12];
m.m[13] = matrixLeft.m[13] - matrixRight.m[13];
m.m[14] = matrixLeft.m[14] - matrixRight.m[14];
m.m[15] = matrixLeft.m[15] - matrixRight.m[15];
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4Translate(GLKMatrix4 matrix, float tx, float ty, float tz)
{
GLKMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3],
matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7],
matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11],
matrix.m[0] * tx + matrix.m[4] * ty + matrix.m[8] * tz + matrix.m[12],
matrix.m[1] * tx + matrix.m[5] * ty + matrix.m[9] * tz + matrix.m[13],
matrix.m[2] * tx + matrix.m[6] * ty + matrix.m[10] * tz + matrix.m[14],
matrix.m[15] };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4TranslateWithVector3(GLKMatrix4 matrix, GLKVector3 translationVector)
{
GLKMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3],
matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7],
matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11],
matrix.m[0] * translationVector.v[0] + matrix.m[4] * translationVector.v[1] + matrix.m[8] * translationVector.v[2] + matrix.m[12],
matrix.m[1] * translationVector.v[0] + matrix.m[5] * translationVector.v[1] + matrix.m[9] * translationVector.v[2] + matrix.m[13],
matrix.m[2] * translationVector.v[0] + matrix.m[6] * translationVector.v[1] + matrix.m[10] * translationVector.v[2] + matrix.m[14],
matrix.m[15] };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4TranslateWithVector4(GLKMatrix4 matrix, GLKVector4 translationVector)
{
GLKMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3],
matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7],
matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11],
matrix.m[0] * translationVector.v[0] + matrix.m[4] * translationVector.v[1] + matrix.m[8] * translationVector.v[2] + matrix.m[12],
matrix.m[1] * translationVector.v[0] + matrix.m[5] * translationVector.v[1] + matrix.m[9] * translationVector.v[2] + matrix.m[13],
matrix.m[2] * translationVector.v[0] + matrix.m[6] * translationVector.v[1] + matrix.m[10] * translationVector.v[2] + matrix.m[14],
matrix.m[15] };
return m;
}
static __inline__ GLKMatrix4 GLKMatrix4Scale(GLKMatrix4 matrix, float sx, float sy, float sz)
{
#if defined(__ARM_NEON__)
float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix;
float32x4x4_t m;
m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)sx);
m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)sy);
m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)sz);
m.val[3] = iMatrix.val[3];
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m = { matrix.m[0] * sx, matrix.m[1] * sx, matrix.m[2] * sx, matrix.m[3] * sx,
matrix.m[4] * sy, matrix.m[5] * sy, matrix.m[6] * sy, matrix.m[7] * sy,
matrix.m[8] * sz, matrix.m[9] * sz, matrix.m[10] * sz, matrix.m[11] * sz,
matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] };
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4ScaleWithVector3(GLKMatrix4 matrix, GLKVector3 scaleVector)
{
#if defined(__ARM_NEON__)
float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix;
float32x4x4_t m;
m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)scaleVector.v[0]);
m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)scaleVector.v[1]);
m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)scaleVector.v[2]);
m.val[3] = iMatrix.val[3];
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m = { matrix.m[0] * scaleVector.v[0], matrix.m[1] * scaleVector.v[0], matrix.m[2] * scaleVector.v[0], matrix.m[3] * scaleVector.v[0],
matrix.m[4] * scaleVector.v[1], matrix.m[5] * scaleVector.v[1], matrix.m[6] * scaleVector.v[1], matrix.m[7] * scaleVector.v[1],
matrix.m[8] * scaleVector.v[2], matrix.m[9] * scaleVector.v[2], matrix.m[10] * scaleVector.v[2], matrix.m[11] * scaleVector.v[2],
matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] };
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4ScaleWithVector4(GLKMatrix4 matrix, GLKVector4 scaleVector)
{
#if defined(__ARM_NEON__)
float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix;
float32x4x4_t m;
m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)scaleVector.v[0]);
m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)scaleVector.v[1]);
m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)scaleVector.v[2]);
m.val[3] = iMatrix.val[3];
return *(GLKMatrix4 *)&m;
#else
GLKMatrix4 m = { matrix.m[0] * scaleVector.v[0], matrix.m[1] * scaleVector.v[0], matrix.m[2] * scaleVector.v[0], matrix.m[3] * scaleVector.v[0],
matrix.m[4] * scaleVector.v[1], matrix.m[5] * scaleVector.v[1], matrix.m[6] * scaleVector.v[1], matrix.m[7] * scaleVector.v[1],
matrix.m[8] * scaleVector.v[2], matrix.m[9] * scaleVector.v[2], matrix.m[10] * scaleVector.v[2], matrix.m[11] * scaleVector.v[2],
matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] };
return m;
#endif
}
static __inline__ GLKMatrix4 GLKMatrix4Rotate(GLKMatrix4 matrix, float radians, float x, float y, float z)
{
GLKMatrix4 rm = GLKMatrix4MakeRotation(radians, x, y, z);
return GLKMatrix4Multiply(matrix, rm);
}
static __inline__ GLKMatrix4 GLKMatrix4RotateWithVector3(GLKMatrix4 matrix, float radians, GLKVector3 axisVector)
{
GLKMatrix4 rm = GLKMatrix4MakeRotation(radians, axisVector.v[0], axisVector.v[1], axisVector.v[2]);
return GLKMatrix4Multiply(matrix, rm);
}
static __inline__ GLKMatrix4 GLKMatrix4RotateWithVector4(GLKMatrix4 matrix, float radians, GLKVector4 axisVector)
{
GLKMatrix4 rm = GLKMatrix4MakeRotation(radians, axisVector.v[0], axisVector.v[1], axisVector.v[2]);
return GLKMatrix4Multiply(matrix, rm);
}
static __inline__ GLKMatrix4 GLKMatrix4RotateX(GLKMatrix4 matrix, float radians)
{
GLKMatrix4 rm = GLKMatrix4MakeXRotation(radians);
return GLKMatrix4Multiply(matrix, rm);
}
static __inline__ GLKMatrix4 GLKMatrix4RotateY(GLKMatrix4 matrix, float radians)
{
GLKMatrix4 rm = GLKMatrix4MakeYRotation(radians);
return GLKMatrix4Multiply(matrix, rm);
}
static __inline__ GLKMatrix4 GLKMatrix4RotateZ(GLKMatrix4 matrix, float radians)
{
GLKMatrix4 rm = GLKMatrix4MakeZRotation(radians);
return GLKMatrix4Multiply(matrix, rm);
}
static __inline__ GLKVector3 GLKMatrix4MultiplyVector3(GLKMatrix4 matrixLeft, GLKVector3 vectorRight)
{
GLKVector4 v4 = GLKMatrix4MultiplyVector4(matrixLeft, GLKVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 0.0f));
return GLKVector3Make(v4.v[0], v4.v[1], v4.v[2]);
}
static __inline__ GLKVector3 GLKMatrix4MultiplyVector3WithTranslation(GLKMatrix4 matrixLeft, GLKVector3 vectorRight)
{
GLKVector4 v4 = GLKMatrix4MultiplyVector4(matrixLeft, GLKVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 1.0f));
return GLKVector3Make(v4.v[0], v4.v[1], v4.v[2]);
}
static __inline__ GLKVector3 GLKMatrix4MultiplyAndProjectVector3(GLKMatrix4 matrixLeft, GLKVector3 vectorRight)
{
GLKVector4 v4 = GLKMatrix4MultiplyVector4(matrixLeft, GLKVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 1.0f));
return GLKVector3MultiplyScalar(GLKVector3Make(v4.v[0], v4.v[1], v4.v[2]), 1.0f / v4.v[3]);
}
static __inline__ void GLKMatrix4MultiplyVector3Array(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount)
{
size_t i;
for (i=0; i < vectorCount; i++)
vectors[i] = GLKMatrix4MultiplyVector3(matrix, vectors[i]);
}
static __inline__ void GLKMatrix4MultiplyVector3ArrayWithTranslation(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount)
{
size_t i;
for (i=0; i < vectorCount; i++)
vectors[i] = GLKMatrix4MultiplyVector3WithTranslation(matrix, vectors[i]);
}
static __inline__ void GLKMatrix4MultiplyAndProjectVector3Array(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount)
{
size_t i;
for (i=0; i < vectorCount; i++)
vectors[i] = GLKMatrix4MultiplyAndProjectVector3(matrix, vectors[i]);
}
static __inline__ GLKVector4 GLKMatrix4MultiplyVector4(GLKMatrix4 matrixLeft, GLKVector4 vectorRight)
{
#if defined(__ARM_NEON__)
float32x4x4_t iMatrix = *(float32x4x4_t *)&matrixLeft;
float32x4_t v;
iMatrix.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)vectorRight.v[0]);
iMatrix.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)vectorRight.v[1]);
iMatrix.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)vectorRight.v[2]);
iMatrix.val[3] = vmulq_n_f32(iMatrix.val[3], (float32_t)vectorRight.v[3]);
iMatrix.val[0] = vaddq_f32(iMatrix.val[0], iMatrix.val[1]);
iMatrix.val[2] = vaddq_f32(iMatrix.val[2], iMatrix.val[3]);
v = vaddq_f32(iMatrix.val[0], iMatrix.val[2]);
return *(GLKVector4 *)&v;
#else
GLKVector4 v = { matrixLeft.m[0] * vectorRight.v[0] + matrixLeft.m[4] * vectorRight.v[1] + matrixLeft.m[8] * vectorRight.v[2] + matrixLeft.m[12] * vectorRight.v[3],
matrixLeft.m[1] * vectorRight.v[0] + matrixLeft.m[5] * vectorRight.v[1] + matrixLeft.m[9] * vectorRight.v[2] + matrixLeft.m[13] * vectorRight.v[3],
matrixLeft.m[2] * vectorRight.v[0] + matrixLeft.m[6] * vectorRight.v[1] + matrixLeft.m[10] * vectorRight.v[2] + matrixLeft.m[14] * vectorRight.v[3],
matrixLeft.m[3] * vectorRight.v[0] + matrixLeft.m[7] * vectorRight.v[1] + matrixLeft.m[11] * vectorRight.v[2] + matrixLeft.m[15] * vectorRight.v[3] };
return v;
#endif
}
static __inline__ void GLKMatrix4MultiplyVector4Array(GLKMatrix4 matrix, GLKVector4 *vectors, size_t vectorCount)
{
size_t i;
for (i=0; i < vectorCount; i++)
vectors[i] = GLKMatrix4MultiplyVector4(matrix, vectors[i]);
}
#ifdef __cplusplus
}
#endif
#endif /* __GLK_MATRIX_4_H */

99
samples/C/NWMan.h Normal file
View File

@@ -0,0 +1,99 @@
#ifndef _NME_WMAN_H
#define _NME_WMAN_H
// Internal window manager API
#include "NCompat.h"
START_HEAD
#include "NPos.h"
#include "NUtil.h"
#include "NTypes.h"
NTS(NWMan_event);
NSTRUCT(NWMan, {
// Init stuff
bool (*init)();
bool (*destroy)();
// Window stuff
bool (*create_window)();
bool (*destroy_window)();
void (*swap_buffers)();
// Event stuff
bool (*next_event)(NWMan_event* event);
// Time stuff
uint (*get_millis)();
void (*sleep)(uint millis);
// Info
int rshift_key;
int lshift_key;
int left_key;
int right_key;
});
NENUM(NWMan_event_type, {
N_WMAN_MOUSE_MOVE = 0,
N_WMAN_MOUSE_BUTTON = 1,
N_WMAN_MOUSE_WHEEL = 2,
N_WMAN_KEYBOARD = 10,
N_WMAN_QUIT = 20,
N_WMAN_RESIZE = 21,
N_WMAN_FOCUS = 22
});
#define N_WMAN_MOUSE_LEFT 0
#define N_WMAN_MOUSE_RIGHT 1
#define N_WMAN_MOUSE_MIDDLE 2
NSTRUCT(NWMan_event, {
NWMan_event_type type;
union {
// Mouse
NPos2i mouse_pos;
struct {
short id;
bool state;
} mouse_button;
signed char mouse_wheel; // 1 if up, -1 if down
// Keyboard
struct {
int key;
bool state;
} keyboard;
// Window
bool window_quit; // Will always be true if WM_QUIT
NPos2i window_size;
bool window_focus;
};
});
NWMan_event NWMan_event_new(NWMan_event_type type);
bool NWMan_init();
bool NWMan_destroy();
extern NWMan N_WMan;
END_HEAD
#endif

27
samples/C/Nightmare.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef _NMEX_NIGHTMARE_H
#define _NMEX_NIGHTMARE_H
//#define NMEX
#include "../src/NCompat.h"
START_HEAD
#include "../src/NTypes.h"
#include "../src/NUtil.h"
#include "../src/NPorting.h"
#include "../src/NGlobals.h"
#include "../src/NLog.h"
#include "../src/NWMan.h"
#include "../src/NRsc.h"
#include "../src/NShader.h"
#include "../src/NSquare.h"
#include "../src/NImage.h"
#include "../src/NSprite.h"
#include "../src/NSpritesheet.h"
#include "../src/NEntity.h"
#include "../src/Game.h"
END_HEAD
#endif

89
samples/C/ntru_encrypt.h Normal file
View File

@@ -0,0 +1,89 @@
/*
* Copyright (C) 2014 FH Bielefeld
*
* This file is part of a FH Bielefeld project.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
/**
* @file ntru_encrypt.h
* Header for the internal API of ntru_encrypt.c.
* @brief header for encrypt.c
*/
#ifndef PQC_ENCRYPT_H
#define PQC_ENCRYPT_H
#include "ntru_params.h"
#include "ntru_poly.h"
#include "ntru_string.h"
#include <fmpz_poly.h>
#include <fmpz.h>
/**
* encrypt the msg, using the math:
* e = (h r) + m (mod q)
*
* e = the encrypted poly
*
* h = the public key
*
* r = the random poly
*
* m = the message poly
*
* q = large mod
*
* @param msg_tern the message to encrypt, in ternary format
* @param pub_key the public key
* @param rnd the random poly (should have relatively small
* coefficients, but not restricted to {-1, 0, 1})
* @param out the output poly which is in the range {0, q-1}
* (not ternary!) [out]
* @param params ntru_params the ntru context
*/
void
ntru_encrypt_poly(
const fmpz_poly_t msg_tern,
const fmpz_poly_t pub_key,
const fmpz_poly_t rnd,
fmpz_poly_t out,
const ntru_params *params);
/**
* Encrypt a message in the form of a null-terminated char array and
* return a string.
*
* @param msg the message
* @param pub_key the public key
* @param rnd the random poly (should have relatively small
* coefficients, but not restricted to {-1, 0, 1})
* @param params ntru_params the ntru context
* @return the newly allocated encrypted string
*/
string *
ntru_encrypt_string(
const string *msg,
const fmpz_poly_t pub_key,
const fmpz_poly_t rnd,
const ntru_params *params);
#endif /* PQC_ENCRYPT_H */

View File

@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 2.8)
project(Foo)
set(CMAKE_SKIP_RPATH TRUE)
set(CMAKE_INSTALL_PREFIX "/usr/local")
add_subdirectory(bar)
add_executable(foo foo.c)
target_link_libraries(foo pthread)
install(TARGETS foo DESTINATION bin)

View File

@@ -1,13 +1,13 @@
doc "Test function for Ceylon"
by "Enrique"
"Test function for Ceylon"
by ("Enrique")
shared void test() {
print("test");
print("test");
}
doc "Test class for Ceylon"
"Test class for Ceylon"
shared class Test(name) satisfies Comparable<Test> {
shared String name;
shared actual String string = "Test " name ".";
shared actual String string = "Test ``name``.";
shared actual Comparison compare(Test other) {
return name<=>other.name;

11
samples/Clean/GenHylo.dcl Normal file
View File

@@ -0,0 +1,11 @@
definition module GenHylo
import StdGeneric, GenMap
:: Fix f = In (f .(Fix f))
Out :: !u:(Fix v:a) -> v:(a w:(Fix v:a)), [u <= w]
hylo :: ((.f .b) -> .b) (.a -> (.f .a)) -> (.a -> .b) | gMap{|*->*|} f
cata :: (u:(f .a) -> .a) -> (Fix u:f) -> .a | gMap{|*->*|} f
ana :: (.a -> u:(f .a)) -> .a -> (Fix u:f) | gMap{|*->*|} f

9
samples/Clean/GenMap.dcl Normal file
View File

@@ -0,0 +1,9 @@
definition module GenMap
import StdGeneric
generic gMap a b :: .a -> .b
derive gMap c, UNIT, PAIR, EITHER, CONS, FIELD, OBJECT, {}, {!}
derive gMap [], (,), (,,), (,,,), (,,,,), (,,,,,), (,,,,,,), (,,,,,,,)

19
samples/Clean/GenMap.icl Normal file
View File

@@ -0,0 +1,19 @@
implementation module GenMap
import StdClass, StdArray, StdInt, StdFunc
import StdGeneric, _Array
generic gMap a b :: .a -> .b
gMap{|c|} x = x
gMap{|UNIT|} x = x
gMap{|PAIR|} fx fy (PAIR x y) = PAIR (fx x) (fy y)
gMap{|EITHER|} fl fr (LEFT x) = LEFT (fl x)
gMap{|EITHER|} fl fr (RIGHT x) = RIGHT (fr x)
gMap{|CONS|} f (CONS x) = CONS (f x)
gMap{|FIELD|} f (FIELD x) = FIELD (f x)
gMap{|OBJECT|} f (OBJECT x) = OBJECT (f x)
gMap{|{}|} f xs = mapArray f xs
gMap{|{!}|} f xs = mapArray f xs
derive gMap [], (,), (,,), (,,,), (,,,,), (,,,,,), (,,,,,,), (,,,,,,,)

54
samples/Clean/fsieve.icl Normal file
View File

@@ -0,0 +1,54 @@
module fsieve
/*
The Fast Sieve of Eratosthenes.
A sequential and optimized version of the sieve of Eratosthenes.
The program calculates a list of the first NrOfPrime primes.
The result of the program is the NrOfPrimes'th prime.
Strictness annotations have been added because the strictness analyser
is not able to deduce all strictness information. Removal of these !'s
will make the program about 20% slower.
On a machine without a math coprocessor the execution of this
program might take a (very) long time. Set NrOfPrimes to a smaller value.
*/
import StdClass; // RWS
import StdInt, StdReal
NrOfPrimes :== 3000
// The sieve algorithm: generate an infinite list of all primes.
Primes::[Int]
Primes = pr where pr = [5 : Sieve 7 4 pr]
Sieve::Int !Int [Int] -> [Int]
Sieve g i prs
| IsPrime prs g (toInt (sqrt (toReal g))) = [g : Sieve` g i prs]
= Sieve (g + i) (6 - i) prs
Sieve`::Int Int [Int] -> [Int]
Sieve` g i prs = Sieve (g + i) (6 - i) prs
IsPrime::[Int] !Int Int -> Bool
IsPrime [f:r] pr bd | f>bd = True
| pr rem f==0 = False
= IsPrime r pr bd
// Select is used to get the NrOfPrimes'th prime from the infinite list.
Select::[x] Int -> x
Select [f:r] 1 = f
Select [f:r] n = Select r (n - 1)
/* The Start rule: Select the NrOfPrimes'th prime from the list of primes
generated by Primes.
*/
Start::Int
Start = Select [2, 3 : Primes] NrOfPrimes

99
samples/Clean/sem.icl Normal file
View File

@@ -0,0 +1,99 @@
module monadicSemantics
import StdEnv, StdGeneric, GenMap, GenHylo
/* For fun I implemented the recursive datastructre Exp and Stm as fixpoints
This helps us define recursive functions on them (only a little bit though)
However deriving gMap for Fix did not works out of the box
I had to remove some uniqueness typing in GenMap and GenHylo */
:: Op = Plus | Minus | Times | Rem | Equal | LessThan
:: Var :== String
:: ExpP a = Int Int | Var Var | Op Op a a
:: Exp :== Fix ExpP
:: StmP a = Assign Var Exp | If Exp a a | While Exp a | Seq a a | Cont
:: Stm :== Fix StmP
derive gMap ExpP, StmP, Fix
// Environment. Semantics is basically Env -> Env
:: Env :== Var -> Int
:: Sem :== Env -> (Int, Env)
empty = \v . 0
// return
rtn :: Int -> Sem
rtn i = \e. (i, e)
// the usual bind
(>>=) infixl 1 :: Sem (Int->Sem) -> Sem
(>>=) x y = \e. (\(i,e2).y i e2) (x e)
(>>|) infixl 1 :: Sem Sem -> Sem
(>>|) x y = x >>= \_. y
// read variable from environment
read :: Var -> Sem
read v = \e. (e v, e)
// assign value to give variable in environment
write :: Var Int -> Sem
write v i = \e. (i, \w. if (w==v) i (e w))
// semantics
class sem a :: a -> Sem
operator :: Op -> Int -> Int -> Int
operator Plus = (+)
operator Minus = (-)
operator Times = (*)
operator Rem = rem
operator Equal = \x y . if (x==y) 1 0
operator LessThan = \x y . if (x< y) 1 0
// semantics of expressions
instance sem Exp where
sem x = cata phi x where
phi (Int n) = rtn n
phi (Var v) = read v
phi (Op op x y) = x >>= \v1. y >>= return o (operator op v1)
// semantics of statments
// NOTE: while will always return 0, as it might not even be executed
instance sem Stm where
sem x = cata phi x where
phi (Assign v e) = sem e >>= write v
phi (If e s1 s2) = sem e >>= \b . if (b<>0) s1 s2
phi stm=:(While e s) = sem e >>= \b . if (b<>0) (s >>| phi stm) (phi Cont)
phi (Seq s1 s2) = s1 >>| s2 // Here the cata *finally* pays off :D
phi Cont = rtn 0
// convenience functions
int = In o Int
var = In o Var
op o = In o2 (Op o)
assign = In o2 Assign
ifte e = In o2 (If e)
while = In o2 While
seq = In o2 Seq
cont = In Cont
// test case, also testing the new operator <
pEuclides =
while (op LessThan (int 0) (var "b"))(
seq (assign "r" (op Rem (var "a") (var "b")))
(seq (assign "a" (var "b"))
( (assign "b" (var "r")))
)
)
Start = fst (program start) where
program = sem pEuclides >>| read "a"
start "a" = 9
start "b" = 12
start _ = 0
// Helper
(o2) infixr 9
(o2) f g x :== f o (g x)

14
samples/Clean/stack.dcl Normal file
View File

@@ -0,0 +1,14 @@
definition module stack
:: Stack a
newStack :: (Stack a)
push :: a (Stack a) -> Stack a
pushes :: [a] (Stack a) -> Stack a
pop :: (Stack a) -> Stack a
popn :: Int (Stack a) -> Stack a
top :: (Stack a) -> a
topn :: Int (Stack a) -> [a]
elements :: (Stack a) -> [a]
count :: (Stack a) -> Int

33
samples/Clean/stack.icl Normal file
View File

@@ -0,0 +1,33 @@
implementation module stack
import StdEnv
:: Stack a :== [a]
newStack :: (Stack a)
newStack = []
push :: a (Stack a) -> Stack a
push x s = [x:s]
pushes :: [a] (Stack a) -> Stack a
pushes x s = x ++ s
pop :: (Stack a) -> Stack a
pop [] = abort "Cannot use pop on an empty stack"
pop [e:s] = s
popn :: Int (Stack a) -> Stack a
popn n s = drop n s
top :: (Stack a) -> a
top [] = abort "Cannot use top on an empty stack"
top [e:s] = e
topn :: Int (Stack a) -> [a]
topn n s = take n s
elements :: (Stack a) -> [a]
elements s = s
count :: (Stack a) -> Int
count s = length s

16
samples/Clean/streams.dcl Normal file
View File

@@ -0,0 +1,16 @@
definition module streams
import StdEnv
instance zero [Real]
instance one [Real]
instance + [Real]
instance - [Real]
instance * [Real]
instance / [Real]
X :: [Real]
invert :: [Real] -> [Real]
pow :: [Real] Int -> [Real]
(shuffle) infixl 7 :: [Real] [Real] -> [Real]

49
samples/Clean/streams.icl Normal file
View File

@@ -0,0 +1,49 @@
implementation module streams
import StdEnv
instance zero [Real]
where
zero = [] //Infinite row of zeroes represented as empty list to ease computation
instance one [Real]
where
one = [1.0:zero]
instance + [Real]
where
(+) [s:s`] [t:t`] = [s+t:s`+t`]
(+) [s:s`] [] = [s:s`]
(+) [] [t:t`] = [t:t`]
(+) [] [] = []
instance - [Real]
where
(-) [s:s`] [t:t`] = [s-t:s`-t`]
(-) [s:s`] [] = [s:s`]
(-) [] [t:t`] = [-1.0] * [t:t`]
(-) [] [] = []
instance * [Real]
where
(*) [s:s`] [t:t`] = [s*t:s`*[t:t`]+[s]*t`]
(*) _ _ = []
instance / [Real]
where
(/) s t = s * (invert t)
X :: [Real]
X = [0.0:one]
invert :: [Real] -> [Real]
invert [s:s`] = [1.0/s:(invert [s:s`]) * s` * [-1.0/s]]
pow :: [Real] Int -> [Real]
pow s 0 = one
pow s n = s * pow s (n-1)
(shuffle) infixl 7 :: [Real] [Real] -> [Real]
(shuffle) [s:s`] [t:t`] = [s*t:s` shuffle [t:t`] + [s:s`] shuffle t`]
(shuffle) _ _ = []

View File

@@ -0,0 +1,40 @@
###* @cjsx React.DOM ###
define 'myProject.ReactExampleComponent', [
'React'
'myProject.ExampleStore'
'myProject.ExampleActions'
'myProject.ReactExampleTable'
], (React, ExampleStore, ExampleActions, ReactExampleTable ) ->
ReactExampleComponent = React.createClass
mixins: [ListenMixin]
getInitialState: ->
rows: ExampleStore.getRows()
meta: ExampleStore.getMeta()
componentWillMount: ->
@listenTo ExampleStore
componentDidMount: ->
ExampleActions.getExampleData()
onStoreChange: ->
if this.isMounted()
@setState
rows: ExampleStore.getRows()
meta: ExampleStore.getMeta()
componentWillUnmount: ->
@stopListening ExampleStore
render: ->
<div className="page-wrap">
<header>
<strong> {@state.title} </strong>
<header>
<ReactExampleTable
rows={@state.rows},
meta={@state.meta}
/>
</div>

26
samples/Cool/list.cl Normal file
View File

@@ -0,0 +1,26 @@
(* This simple example of a list class is adapted from an example in the
Cool distribution. *)
class List {
isNil() : Bool { true };
head() : Int { { abort(); 0; } };
tail() : List { { abort(); self; } };
cons(i : Int) : List {
(new Cons).init(i, self)
};
};
class Cons inherits List {
car : Int; -- The element in this list cell
cdr : List; -- The rest of the list
isNil() : Bool { false };
head() : Int { car };
tail() : List { cdr };
init(i : Int, rest : List) : List {
{
car <- i;
cdr <- rest;
self;
}
};
};

71
samples/Cool/sample.cl Normal file
View File

@@ -0,0 +1,71 @@
(* Refer to Alex Aiken, "The Cool Reference Manual":
http://theory.stanford.edu/~aiken/software/cool/cool-manual.pdf
for language specification.
*)
-- Exhibit various language constructs
class Sample {
testCondition(x: Int): Bool {
if x = 0
then false
else
if x < (1 + 2) * 3
then true
else false
fi
fi
};
testLoop(y: Int): Bool {
while y > 0 loop
{
if not condition(y)
then y <- y / 2
else y <- y - 1;
}
pool
};
testAssign(z: Int): Bool {
i : Int;
i <- ~z;
};
testCase(var: Sample): SELF_TYPE {
io : IO <- new IO;
case var of
a : A => io.out_string("Class type is A\n");
b : B => io.out_string("Class type is B\n");
s : Sample => io.out_string("Class type is Sample\n");
o : Object => io.out_string("Class type is object\n");
esac
};
testLet(i: Int): Int {
let (a: Int in
let(b: Int <- 3, c: Int <- 4 in
{
a <- 2;
a * b * 2 / c;
}
)
)
};
};
-- Used to test subclasses
class A inherits Sample {};
class B inherits A {};
class C {
main() : Int {
(new Sample).testLet(1)
};
};
-- "Hello, world" example
class Main inherits IO {
main(): SELF_TYPE {
out_string("Hello, World.\n")
};
};

49
samples/F#/Combinators.fs Normal file
View File

@@ -0,0 +1,49 @@
namespace Nessos.FsPickler.Combinators
open Nessos.FsPickler
open Nessos.FsPickler.Json
/// Json pickling methods
[<RequireQualifiedAccess>]
module Json =
let private jsonSerializer = lazy(FsPickler.CreateJson(omitHeader = true))
/// <summary>
/// Pickles a value to Json.
/// </summary>
/// <param name="pickler">utilized pickler.</param>
/// <param name="value">input value.</param>
let pickle (pickler : Pickler<'T>) (value : 'T) : string =
jsonSerializer.Value.PickleToString (pickler, value)
/// <summary>
/// Unpickles a value from Json.
/// </summary>
/// <param name="pickler">utilized pickler.</param>
/// <param name="pickle">input pickle.</param>
let unpickle (pickler : Pickler<'T>) (pickle : string) : 'T =
jsonSerializer.Value.UnPickleOfString (pickler, pickle)
/// Bson pickling methods
[<RequireQualifiedAccess>]
module Bson =
let private bsonPickler = lazy(FsPickler.CreateBson())
/// <summary>
/// Pickles a value to Bson.
/// </summary>
/// <param name="pickler">utilized pickler.</param>
/// <param name="value">input value.</param>
let pickle (pickler : Pickler<'T>) (value : 'T) : byte [] =
bsonPickler.Value.Pickle (pickler, value)
/// <summary>
/// Unpickles a value from bson.
/// </summary>
/// <param name="pickler">utilized pickler.</param>
/// <param name="pickle">input pickle.</param>
let unpickle (pickler : Pickler<'T>) (pickle : byte []) : 'T =
bsonPickler.Value.UnPickle (pickler, pickle)

65
samples/F#/JsonFormat.fs Normal file
View File

@@ -0,0 +1,65 @@
namespace Nessos.FsPickler.Json
open System
open System.IO
open System.Text
open Newtonsoft.Json
open Nessos.FsPickler
/// <summary>
/// Factory methods for the Json serialization format.
/// </summary>
type JsonPickleFormatProvider internal (indent, omitHeader) as self =
let isCustomSeq isTopLevelSequence =
isTopLevelSequence && self.OmitHeader && self.UseCustomTopLevelSequenceSeparator
let mutable sequenceSeparator = " "
member val Indent = indent with get,set
member val OmitHeader = omitHeader with get,set
member val UseCustomTopLevelSequenceSeparator = false with get,set
member __.SequenceSeparator
with get () = sequenceSeparator
and set sep =
if sep <> null && String.IsNullOrWhiteSpace sep then
sequenceSeparator <- sep
else
invalidArg "SequenceSeparator" "should be non-null whitespace."
interface ITextPickleFormatProvider with
member __.Name = "Json"
// see discussion : https://github.com/nessos/FsPickler/issues/17
member __.DefaultEncoding = new UTF8Encoding(false) :> Encoding
member __.CreateWriter (stream, encoding, isTopLevelSequence, leaveOpen) =
#if NET40
if leaveOpen then raise <| new NotSupportedException("'leaveOpen' not supported in .NET 40.")
let sw = new StreamWriter(stream, encoding)
#else
let sw = new StreamWriter(stream, encoding, 1024, leaveOpen)
#endif
let jw = new JsonTextWriter(sw)
new JsonPickleWriter(jw, __.OmitHeader, __.Indent, isCustomSeq isTopLevelSequence, sequenceSeparator, leaveOpen) :> _
member __.CreateReader (stream, encoding, isTopLevelSequence, leaveOpen) =
#if NET40
if leaveOpen then raise <| new NotSupportedException("'leaveOpen' not supported in .NET 40.")
let sr = new StreamReader(stream, encoding)
#else
let sr = new StreamReader(stream, encoding, true, 1024, leaveOpen)
#endif
let jr = new JsonTextReader(sr)
new JsonPickleReader(jr, __.OmitHeader, isCustomSeq isTopLevelSequence, leaveOpen) :> _
member __.CreateWriter (textWriter, isTopLevelSequence, leaveOpen) =
let jw = new JsonTextWriter(textWriter)
new JsonPickleWriter(jw, __.OmitHeader, __.Indent, isCustomSeq isTopLevelSequence, sequenceSeparator, leaveOpen) :> _
member __.CreateReader (textReader, isTopLevelSequence, leaveOpen) =
let jr = new JsonTextReader(textReader)
new JsonPickleReader(jr, __.OmitHeader, isCustomSeq isTopLevelSequence, leaveOpen) :> _

202
samples/F#/JsonReader.fs Normal file
View File

@@ -0,0 +1,202 @@
namespace Nessos.FsPickler.Json
open System
open System.Collections.Generic
open System.Globalization
open System.IO
open System.Numerics
open System.Text
open Newtonsoft.Json
open Nessos.FsPickler
/// <summary>
/// Json format deserializer
/// </summary>
type internal JsonPickleReader (jsonReader : JsonReader, omitHeader, isTopLevelSequence, leaveOpen) =
do
jsonReader.CloseInput <- not leaveOpen
jsonReader.SupportMultipleContent <- isTopLevelSequence
let isBsonReader = match jsonReader with :? Bson.BsonReader -> true | _ -> false
let mutable depth = 0
let arrayStack = new Stack<int> ()
do arrayStack.Push Int32.MinValue
// do not write tag if omitting header or array element
let omitTag () = (omitHeader && depth = 0) || arrayStack.Peek() = depth - 1
interface IPickleFormatReader with
member __.BeginReadRoot (tag : string) =
do jsonReader.Read() |> ignore
if omitHeader then () else
if jsonReader.TokenType <> JsonToken.StartObject then raise <| new FormatException("invalid json root object.")
else
do jsonReader.MoveNext()
let version = jsonReader.ReadPrimitiveAs<string> false "FsPickler"
if version <> jsonFormatVersion then
let v = Version(version)
raise <| new FormatException(sprintf "Invalid FsPickler format version %O." version)
let sTag = jsonReader.ReadPrimitiveAs<string> false "type"
if tag <> sTag then
raise <| new InvalidPickleTypeException(tag, sTag)
member __.EndReadRoot () =
if not omitHeader then jsonReader.Read() |> ignore
member __.BeginReadObject (tag : string) =
if not <| omitTag () then
jsonReader.ReadProperty tag
jsonReader.MoveNext ()
if isTopLevelSequence && depth = 0 then
arrayStack.Push depth
depth <- depth + 1
ObjectFlags.IsSequenceHeader
else
match jsonReader.TokenType with
| JsonToken.Null -> ObjectFlags.IsNull
| JsonToken.StartArray ->
jsonReader.MoveNext()
arrayStack.Push depth
depth <- depth + 1
ObjectFlags.IsSequenceHeader
| JsonToken.StartObject ->
do jsonReader.MoveNext()
depth <- depth + 1
if jsonReader.ValueAs<string> () = "_flags" then
jsonReader.MoveNext()
let csvFlags = jsonReader.ValueAs<string>()
jsonReader.MoveNext()
parseFlagCsv csvFlags
else
ObjectFlags.None
| token -> raise <| new FormatException(sprintf "expected start of Json object but was '%O'." token)
member __.EndReadObject () =
if isTopLevelSequence && depth = 1 then
arrayStack.Pop () |> ignore
depth <- depth - 1
jsonReader.Read() |> ignore
else
match jsonReader.TokenType with
| JsonToken.Null -> ()
| JsonToken.EndObject -> depth <- depth - 1
| JsonToken.EndArray ->
arrayStack.Pop() |> ignore
depth <- depth - 1
| token -> raise <| new FormatException(sprintf "expected end of Json object but was '%O'." token)
if omitHeader && depth = 0 then ()
else jsonReader.Read() |> ignore
member __.SerializeUnionCaseNames = true
member __.PreferLengthPrefixInSequences = false
member __.ReadNextSequenceElement () =
if isTopLevelSequence && depth = 1 then
jsonReader.TokenType <> JsonToken.None
else
jsonReader.TokenType <> JsonToken.EndArray
member __.ReadCachedObjectId () = jsonReader.ReadPrimitiveAs<int64> false "id"
member __.ReadBoolean tag = jsonReader.ReadPrimitiveAs<bool> (omitTag ()) tag
member __.ReadByte tag = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag |> byte
member __.ReadSByte tag = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag |> sbyte
member __.ReadInt16 tag = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag |> int16
member __.ReadInt32 tag = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag |> int
member __.ReadInt64 tag = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag
member __.ReadUInt16 tag = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag |> uint16
member __.ReadUInt32 tag = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag |> uint32
member __.ReadUInt64 tag = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag |> uint64
member __.ReadSingle tag =
if not <| omitTag () then
jsonReader.ReadProperty tag
jsonReader.MoveNext()
let value =
match jsonReader.TokenType with
| JsonToken.Float -> jsonReader.ValueAs<double> () |> single
| JsonToken.String -> Single.Parse(jsonReader.ValueAs<string>(), CultureInfo.InvariantCulture)
| _ -> raise <| new FormatException("not a float.")
jsonReader.Read() |> ignore
value
member __.ReadDouble tag =
if not <| omitTag () then
jsonReader.ReadProperty tag
jsonReader.MoveNext()
let value =
match jsonReader.TokenType with
| JsonToken.Float -> jsonReader.ValueAs<double> ()
| JsonToken.String -> Double.Parse(jsonReader.ValueAs<string>(), CultureInfo.InvariantCulture)
| _ -> raise <| new FormatException("not a float.")
jsonReader.Read() |> ignore
value
member __.ReadChar tag = let value = jsonReader.ReadPrimitiveAs<string> (omitTag ()) tag in value.[0]
member __.ReadString tag = jsonReader.ReadPrimitiveAs<string> (omitTag ()) tag
member __.ReadBigInteger tag = jsonReader.ReadPrimitiveAs<string> (omitTag ()) tag |> BigInteger.Parse
member __.ReadGuid tag =
if isBsonReader then
jsonReader.ReadPrimitiveAs<Guid> (omitTag ()) tag
else
jsonReader.ReadPrimitiveAs<string> (omitTag ()) tag |> Guid.Parse
member __.ReadTimeSpan tag = jsonReader.ReadPrimitiveAs<string> (omitTag ()) tag |> TimeSpan.Parse
member __.ReadDecimal tag = jsonReader.ReadPrimitiveAs<string> (omitTag ()) tag |> decimal
// BSON spec mandates the use of Unix time;
// this has millisecond precision which results in loss of accuracy w.r.t. ticks
// since the goal of FsPickler is to offer faithful representations of .NET objects
// we choose to override the spec and serialize ticks outright.
// see also https://json.codeplex.com/discussions/212067
member __.ReadDate tag =
if isBsonReader then
let ticks = jsonReader.ReadPrimitiveAs<int64> (omitTag ()) tag
DateTime(ticks)
else
jsonReader.ReadPrimitiveAs<DateTime> (omitTag ()) tag
member __.ReadBytes tag =
if not <| omitTag () then
jsonReader.ReadProperty tag
jsonReader.Read() |> ignore
let bytes =
if jsonReader.TokenType = JsonToken.Null then null
elif isBsonReader then jsonReader.ValueAs<byte []> ()
else
let base64 = jsonReader.ValueAs<string> ()
Convert.FromBase64String base64
jsonReader.Read() |> ignore
bytes
member __.IsPrimitiveArraySerializationSupported = false
member __.ReadPrimitiveArray _ _ = raise <| new NotImplementedException()
member __.Dispose () = (jsonReader :> IDisposable).Dispose()

View File

@@ -0,0 +1,85 @@
namespace Nessos.FsPickler.Json
open System
open Nessos.FsPickler
type internal OAttribute = System.Runtime.InteropServices.OptionalAttribute
type internal DAttribute = System.Runtime.InteropServices.DefaultParameterValueAttribute
/// <summary>
/// Json pickler instance.
/// </summary>
type JsonSerializer =
inherit FsPicklerTextSerializer
val private format : JsonPickleFormatProvider
/// <summary>
/// Initializes a new Json pickler instance.
/// </summary>
/// <param name="indent">indent out Json pickles.</param>
/// <param name="omitHeader">omit FsPickler header in Json pickles.</param>
/// <param name="typeConverter">specify a custom type name converter.</param>
new ([<O;D(null)>] ?indent, [<O;D(null)>] ?omitHeader, [<O;D(null)>] ?typeConverter) =
let indent = defaultArg indent false
let omitHeader = defaultArg omitHeader false
let json = new JsonPickleFormatProvider(indent, omitHeader)
{
inherit FsPicklerTextSerializer(json, ?typeConverter = typeConverter)
format = json
}
/// <summary>
/// Gets or sets whether Json output should be indented.
/// </summary>
member x.Indent
with get () = x.format.Indent
and set b = x.format.Indent <- b
/// <summary>
/// Gets or sets whether FsPickler headers should be ignored in pickle format.
/// </summary>
member x.OmitHeader
with get () = x.format.OmitHeader
and set b = x.format.OmitHeader <- b
/// <summary>
/// Gets or sets a non-null whitespace string that serves as a custom, top-level sequence separator.
/// </summary>
member x.SequenceSeparator
with get () = x.format.SequenceSeparator
and set sep = x.format.SequenceSeparator <- sep
/// <summary>
/// Gets or sets whether top-level sequences should be serialized using the custom separator.
/// </summary>
member x.UseCustomTopLevelSequenceSeparator
with get () = x.format.UseCustomTopLevelSequenceSeparator
and set e = x.format.UseCustomTopLevelSequenceSeparator <- e
/// <summary>
/// BSON pickler instance.
/// </summary>
type BsonSerializer([<O;D(null)>] ?typeConverter) =
inherit FsPicklerSerializer(new BsonPickleFormatProvider(), ?typeConverter = typeConverter)
/// FsPickler static methods.
type FsPickler =
/// <summary>
/// Initializes a new Json pickler instance.
/// </summary>
/// <param name="indent">indent out Json pickles.</param>
/// <param name="omitHeader">omit FsPickler header in Json pickles.</param>
/// <param name="typeConverter">specify a custom type name converter.</param>
static member CreateJson([<O;D(null)>] ?indent, [<O;D(null)>] ?omitHeader, [<O;D(null)>] ?typeConverter) =
new JsonSerializer(?indent = indent, ?omitHeader = omitHeader, ?typeConverter = typeConverter)
/// <summary>
/// Initializes a new Bson pickler instance.
/// </summary>
/// <param name="typeConverter">specify a custom type name converter.</param>
static member CreateBson([<O;D(null)>] ?typeConverter) =
new BsonSerializer(?typeConverter = typeConverter)

142
samples/F#/JsonWriter.fs Normal file
View File

@@ -0,0 +1,142 @@
namespace Nessos.FsPickler.Json
open System
open System.IO
open System.Collections.Generic
open Newtonsoft.Json
open Nessos.FsPickler
/// <summary>
/// Json format serializer.
/// </summary>
type internal JsonPickleWriter (jsonWriter : JsonWriter, omitHeader, indented, isTopLevelSequence, separator, leaveOpen) =
do
jsonWriter.Formatting <- if indented then Formatting.Indented else Formatting.None
jsonWriter.CloseOutput <- not leaveOpen
let isBsonWriter = match jsonWriter with :? Bson.BsonWriter -> true | _ -> false
let mutable depth = 0
let mutable isTopLevelSequenceHead = false
let mutable currentValueIsNull = false
let arrayStack = new Stack<int> ()
do arrayStack.Push Int32.MinValue
// do not write tag if omitting header or array element
let omitTag () = (omitHeader && depth = 0) || arrayStack.Peek() = depth - 1
interface IPickleFormatWriter with
member __.BeginWriteRoot (tag : string) =
if omitHeader then () else
jsonWriter.WriteStartObject()
writePrimitive jsonWriter false "FsPickler" jsonFormatVersion
writePrimitive jsonWriter false "type" tag
member __.EndWriteRoot () =
if not omitHeader then jsonWriter.WriteEnd()
member __.BeginWriteObject (tag : string) (flags : ObjectFlags) =
if not <| omitTag () then
jsonWriter.WritePropertyName tag
if flags.HasFlag ObjectFlags.IsNull then
currentValueIsNull <- true
jsonWriter.WriteNull()
elif flags.HasFlag ObjectFlags.IsSequenceHeader then
if isTopLevelSequence && depth = 0 then
isTopLevelSequenceHead <- true
else
jsonWriter.WriteStartArray()
arrayStack.Push depth
depth <- depth + 1
else
jsonWriter.WriteStartObject()
depth <- depth + 1
if flags = ObjectFlags.None then ()
else
let flagCsv = mkFlagCsv flags
writePrimitive jsonWriter false "_flags" flagCsv
member __.EndWriteObject () =
if currentValueIsNull then
currentValueIsNull <- false
else
depth <- depth - 1
if arrayStack.Peek () = depth then
if isTopLevelSequence && depth = 0 then ()
else
jsonWriter.WriteEndArray()
arrayStack.Pop () |> ignore
else
jsonWriter.WriteEndObject()
member __.SerializeUnionCaseNames = true
member __.PreferLengthPrefixInSequences = false
member __.WriteNextSequenceElement hasNext =
if isTopLevelSequence && depth = 1 then
if isTopLevelSequenceHead then
isTopLevelSequenceHead <- false
else
jsonWriter.WriteWhitespace separator
member __.WriteCachedObjectId id = writePrimitive jsonWriter false "id" id
member __.WriteBoolean (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteByte (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteSByte (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteInt16 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteInt32 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteInt64 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteUInt16 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteUInt32 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteUInt64 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteSingle (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteDouble (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteDecimal (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value)
member __.WriteChar (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteString (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteBigInteger (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value)
member __.WriteGuid (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteTimeSpan (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value)
// BSON spec mandates the use of Unix time;
// this has millisecond precision which results in loss of accuracy w.r.t. ticks
// since the goal of FsPickler is to offer faithful representations of .NET objects
// we choose to override the spec and serialize ticks outright.
// see also https://json.codeplex.com/discussions/212067
member __.WriteDate (tag : string) value =
if isBsonWriter then
writePrimitive jsonWriter (omitTag ()) tag value.Ticks
else
writePrimitive jsonWriter (omitTag ()) tag value
member __.WriteBytes (tag : string) (value : byte []) =
if not <| omitTag () then
jsonWriter.WritePropertyName tag
if obj.ReferenceEquals(value, null) then
jsonWriter.WriteNull()
else
jsonWriter.WriteValue value
member __.IsPrimitiveArraySerializationSupported = false
member __.WritePrimitiveArray _ _ = raise <| NotSupportedException()
member __.Dispose () = jsonWriter.Flush()

View File

@@ -0,0 +1,68 @@
namespace Nessos.FsPickler.Tests
open PerfUtil
open PerfUtil.NUnit
open NUnit.Framework
open Nessos.FsPickler
open Nessos.FsPickler.Json
[<AbstractClass>]
type PerfTester () =
inherit NUnitPerf<Serializer> ()
let tests = PerfTest.OfModuleMarker<PerformanceTests.Marker> ()
override __.PerfTests = tests
type ``Serializer Comparison`` () =
inherit PerfTester()
let fsp = FsPickler.initBinary()
let bfs = new BinaryFormatterSerializer() :> Serializer
let ndc = new NetDataContractSerializer() :> Serializer
let jdn = new JsonDotNetSerializer() :> Serializer
let bdn = new JsonDotNetBsonSerializer () :> Serializer
let pbn = new ProtoBufSerializer() :> Serializer
let ssj = new ServiceStackJsonSerializer() :> Serializer
let sst = new ServiceStackTypeSerializer() :> Serializer
let comparer = new WeightedComparer(spaceFactor = 0.2, leastAcceptableImprovementFactor = 1.)
let tester = new ImplementationComparer<_>(fsp, [bfs;ndc;jdn;bdn;pbn;ssj;sst], throwOnError = true, warmup = true, comparer = comparer)
override __.PerfTester = tester :> _
type ``FsPickler Formats Comparison`` () =
inherit PerfTester ()
let binary = FsPickler.initBinary()
let json = FsPickler.initJson()
let bson = FsPickler.initBson()
let xml = FsPickler.initXml()
let tester = new ImplementationComparer<_>(binary, [json ; bson; xml], warmup = true, throwOnError = false)
override __.PerfTester = tester :> _
type ``Past FsPickler Versions Comparison`` () =
inherit PerfTester ()
let persistResults = true
let persistenceFile = "fspPerf.xml"
let fsp = FsPickler.initBinary()
let version = typeof<FsPickler>.Assembly.GetName().Version
let comparer = new WeightedComparer(spaceFactor = 0.2, leastAcceptableImprovementFactor = 0.8)
let tester =
new PastImplementationComparer<Serializer>(
fsp, version, historyFile = persistenceFile, throwOnError = true, warmup = true, comparer = comparer)
override __.PerfTester = tester :> _
[<TestFixtureTearDown>]
member __.Persist() =
if persistResults then tester.PersistCurrentResults ()

View File

@@ -0,0 +1,207 @@
namespace Nessos.FsPickler.Tests
open System
open System.Collections.Generic
open PerfUtil
open Nessos.FsPickler
open Nessos.FsPickler.Tests.Serializer
open Nessos.FsPickler.Tests.TestTypes
module PerformanceTests =
type Marker = class end
let guid = Guid.NewGuid()
[<PerfTest(1000)>]
let ``Value: Guid`` s = roundtrip guid s
let date = DateTime.Now
[<PerfTest(1000)>]
let ``Value: DateTime`` s = roundtrip date s
[<PerfTest(10000)>]
let ``Value: String`` s = roundtrip stringValue s
let boxed = box ([| 1 .. 1000 |], "lorem ipsum")
[<PerfTest(1000)>]
let ``Boxed Object`` s = roundtrip boxed s
let fsClass = new Class(42, stringValue)
[<PerfTest(10000)>]
let ``Class: Simple F# Class`` s = roundtrip fsClass s
let serializableClass = new SerializableClass<_>(42, stringValue, [|1..1000|])
[<PerfTest(10000)>]
let ``Class: ISerializable`` s = roundtrip serializableClass s
let boxedClass = box(Some 42)
[<PerfTest(10000)>]
let ``Subtype Resolution`` s = roundtrip boxedClass s
let floatArray = Array.init 100000 (fun i -> float i)
[<PerfTest(10)>]
let ``Array: Float`` s = roundtrip floatArray s
let intArray = Array.init 100000 id
[<PerfTest(10)>]
let ``Array: Int`` s = roundtrip intArray s
let stringArray = Array.init 10000 (fun i -> stringValue + string i)
[<PerfTest(100)>]
let ``Array: String`` s = roundtrip stringArray s
let kvarr = [|1..10000|] |> Array.map (fun i -> i, string i)
[<PerfTest(100)>]
let ``Array: Key-Value Pairs`` s = roundtrip kvarr s
let duArray = [| for i in 1 .. 10000 -> (Something ("asdasdasdas", i)) |]
[<PerfTest(100)>]
let ``Array: Discriminated Unions`` s = roundtrip duArray s
let objArray =
[|
box 2; box 3; box "hello" ; box <| Some 3; box(2,3) ;
box <| new Class(2, stringValue) ; box <| new SerializableClass<int option>(2, stringValue, Some 12);
box stringValue
|]
[<PerfTest(1000)>]
let ``Array: Objects`` s = roundtrip objArray s
let array3D = Array3D.init 100 100 100 (fun i j k -> float (i * j + k))
[<PerfTest(10)>]
let ``Array: Rank-3 Float`` s = roundtrip array3D s
let bclDict = dict [ for i in 1 .. 1000 -> (string i, i)]
[<PerfTest(100)>]
let ``.NET Dictionary`` s = roundtrip bclDict s
let bclStack = new Stack<string>([for i in 1 .. 1000 -> string i])
[<PerfTest(100)>]
let ``.NET Stack`` s = roundtrip bclStack s
let bclList = new List<string * int>([for i in 1 .. 1000 -> string i, i])
[<PerfTest(100)>]
let ``.NET List`` s = roundtrip bclList s
let bclSet = new SortedSet<_>([for i in 1 .. 1000 -> string i])
[<PerfTest(100)>]
let ``.NET Set`` s = roundtrip bclSet s
let smallTuple = (1, DateTime.Now,"hello")
[<PerfTest(10000)>]
let ``FSharp: Tuple Small`` s = roundtrip smallTuple s
let largeTuple = (stringValue, 1, 2, 3, true, "", Some(3.14, [2]), 3, 2, 1, stringValue)
[<PerfTest(10000)>]
let ``FSharp: Tuple Large`` s =
roundtrip largeTuple s
let intList = [1..1000]
[<PerfTest(1000)>]
let ``FSharp: List Int`` s = roundtrip intList s
let stringList = [ for i in 1 .. 1000 -> stringValue + string i ]
[<PerfTest(1000)>]
let ``FSharp: List String`` s = roundtrip stringList s
let pairList = [ for i in 1 .. 1000 -> (string i, i) ]
[<PerfTest(1000)>]
let ``FSharp: List Key-Value`` s = roundtrip pairList s
let nestedLst = let n = [1..1000] in [for _ in 1 .. 100 -> n]
[<PerfTest(1000)>]
let ``FSharp: List Nested`` s = roundtrip nestedLst s
let union = SomethingElse(stringValue, 42, box (Some 42))
[<PerfTest(10000)>]
let ``FSharp: Union`` s = roundtrip union s
let record = { Int = 42 ; String = stringValue ; Tuple = (13, "") }
[<PerfTest(10000)>]
let ``FSharp: Record`` s = roundtrip record s
let peano = int2Peano 100
[<PerfTest(100)>]
let ``FSharp: Peano Rectype`` s = roundtrip peano s
let closure = (@) [ Some([1..100], Set.ofList [1..100]) ]
[<PerfTest(1000)>]
let ``FSharp: Curried Function`` s = roundtrip closure s
let binTree = mkTree 10
[<PerfTest(100)>]
let ``FSharp: Binary Tree`` s = roundtrip binTree s
let intSet = [1..1000] |> List.map string |> set
[<PerfTest(1000)>]
let ``FSharp: Set`` s = roundtrip intSet s
let fsMap = [1..1000] |> Seq.map (fun i -> (string i,i)) |> Map.ofSeq
[<PerfTest(1000)>]
let ``FSharp: Map`` s = roundtrip fsMap s
let testType = typeof<int * string option * Map<int * string [], string ref option>>
[<PerfTest(1000)>]
let ``Reflection: Type`` s = roundtrip testType s
let quotationSmall = <@ fun x -> pown 2 x @>
let quotationLarge =
<@
async {
let rec fibAsync n =
async {
match n with
| _ when n < 0 -> return invalidArg "negative" "n"
| _ when n < 2 -> return n
| n ->
let! fn = fibAsync (n-1)
let! fnn = fibAsync (n-2)
return fn + fnn
}
let! values = [1..100] |> Seq.map fibAsync |> Async.Parallel
return Seq.sum values
}
@>
[<PerfTest(10000)>]
let ``FSharp: Quotation Small`` s = roundtrip quotationSmall s
[<PerfTest(1000)>]
let ``FSharp: Quotation Large`` s = roundtrip quotationLarge s

15
samples/F#/sample.fs Normal file
View File

@@ -0,0 +1,15 @@
module Sample
open System
type Foo =
{
Bar : string
}
type Baz = interface end
let Sample1(xs : int list) : string =
xs
|> List.map (fun x -> string x)
|> String.concat ","

25
samples/FORTRAN/sample1.f Normal file
View File

@@ -0,0 +1,25 @@
c comment
* comment
program main
end
subroutine foo( i, x, b )
INTEGER i
REAL x
LOGICAL b
if( i.ne.0 ) then
call bar( -i )
end if
return
end
double complex function baz()
baz = (0.0d0,0.0d0)
return
end

View File

@@ -0,0 +1,25 @@
c comment
* comment
program main
end
subroutine foo( i, x, b )
INTEGER i
REAL x
LOGICAL b
if( i.ne.0 ) then
call bar( -i )
end if
return
end
double complex function baz()
baz = (0.0d0,0.0d0)
return
end

25
samples/FORTRAN/sample2.f Normal file
View File

@@ -0,0 +1,25 @@
PROGRAM MAIN
END
C comment
* comment
SUBROUTINE foo( i, x, b )
INTEGER i
REAL x
LOGICAL b
IF( i.NE.0 ) THEN
CALL bar( -i )
END IF
RETURN
END
DOUBLE COMPLEX FUNCTION baz()
baz = (0.0d0,0.0d0)
RETURN
END

25
samples/FORTRAN/sample3.F Normal file
View File

@@ -0,0 +1,25 @@
c comment
* comment
program main
end
subroutine foo( i, x, b )
INTEGER i
REAL x
LOGICAL b
if( i.ne.0 ) then
call bar( -i )
end if
return
end
double complex function baz()
baz = (0.0d0,0.0d0)
return
end

244
samples/Forth/asm.fr Normal file
View File

@@ -0,0 +1,244 @@
\ Copyright 2013-2014 Lars Brinkhoff
\ Assembler for x86.
\ Adds to FORTH vocabulary: ASSEMBLER CODE ;CODE.
\ Creates ASSEMBLER vocabulary with: END-CODE and x86 opcodes.
\ Conventional prefix syntax: "<source> <destination> <opcode>,".
\ Addressing modes:
\ - immediate: "n #"
\ - direct: n
\ - register: <reg>
\ - indirect: "<reg> )"
\ - indirect with displacement: "n <reg> )#"
\ - indexed: not supported yet
require lib/common.fth
require search.fth
vocabulary assembler
also assembler definitions
\ Access to the target image.
' header, defer header, is header,
' cell defer cell is cell
' dp defer dp is dp
0 value delta
: aligned cell + 1 - cell negate nand invert ;
: align dp @ aligned dp ! ;
: allot dp +! ;
: here dp @ ;
: cells cell * ;
: c! delta + c! ;
: c, here c! 1 allot ;
: h, dup c, 8 rshift c, ;
: , dup h, 16 rshift h, ;
base @ hex
\ This constant signals that an operand is not a direct address.
deadbeef constant -addr
\ Assembler state.
variable opcode
variable d
variable s
variable dir?
variable mrrm defer ?mrrm,
variable sib defer ?sib,
variable disp defer ?disp,
variable imm defer ?imm,
defer imm,
defer immediate-opcode
defer reg
defer ?opsize
\ Set opcode. And destination: register or memory.
: opcode! 3@ is immediate-opcode >r opcode ! ;
: !reg dir? @ if 2 d ! then dir? off ;
: !mem dir? off ;
\ Set bits in mod/reg/rm byte.
: -mrrm ['] nop is ?mrrm, ;
: mod! mrrm c0 !bits ;
: reg@ mrrm 38 @bits ;
: reg! mrrm 38 !bits ;
: rm@ mrrm 7 @bits ;
: rm! rm@ 3 lshift reg! mrrm 7 !bits ;
: reg>opcode rm@ opcode 07 !bits ;
: opcode>reg opcode @ dup 3 rshift rm! 8 rshift opcode ! ;
\ Write parts of instruction to memory.
: ds d @ s @ + ;
: ?twobyte dup FF > if dup 8 rshift c, then ;
: opcode, opcode @ ?twobyte ds + c, ;
: mrrm, mrrm @ c, ;
: sib, sib @ c, ;
: imm8, imm @ c, ;
: imm16, imm @ h, ;
: imm32, imm @ , ;
: disp8, disp @ c, ;
: disp32, disp @ , ;
\ Set operand size.
: -opsize 2drop r> drop ;
: opsize! is imm, s ! ['] -opsize is ?opsize ;
: !op8 0 ['] imm8, ?opsize ;
: !op32 1 ['] imm32, ?opsize ;
: !op16 1 ['] imm16, ?opsize 66 c, ;
\ Set SIB byte.
: !sib ['] sib, is ?sib, ;
: sib! 3 lshift + sib ! !sib ;
\ Set displacement.
: byte? -80 80 within ;
: disp! is ?disp, disp ! ;
: !disp8 ['] disp8, disp! ;
: !disp32 ['] disp32, disp! ;
: !disp ( a -- u ) dup byte? if !disp8 40 else !disp32 80 then ;
: -pc here 5 + negate ;
: relative -pc disp +! ;
\ Set immediate operand.
: imm! imm ! ['] imm, is ?imm, ;
\ Implements addressing modes: register, indirect, indexed, and direct.
: reg1 rm! !reg ;
: reg2 3 lshift reg! ;
: !reg2 ['] reg2 is reg ;
: ind dup mod! rm! !mem !reg2 ;
: ind# swap !disp + ind ;
: idx 04 ind sib! ;
: idx# rot !disp 04 + ind sib! ;
: addr !disp32 05 ind ;
\ Reset assembler state.
: 0opsize ['] opsize! is ?opsize ;
: 0ds d off s off ;
: 0reg ['] reg1 is reg ;
: 0mrrm c0 mrrm ! ['] mrrm, is ?mrrm, ;
: 0sib ['] nop is ?sib, ;
: 0disp ['] nop is ?disp, ;
: 0imm imm off ['] nop is ?imm, 0 is imm, ;
: 0asm 0imm 0disp 0reg 0ds 0mrrm 0sib 0opsize dir? on ;
\ Enter and exit assembler mode.
: start-code also assembler 0asm ;
: end-code align previous ;
\ Implements addressing mode: immediate.
: imm8? imm @ byte? ;
: ?sign-extend d off imm8? if 2 d ! ['] imm8, is ?imm, then ;
: alu# opcode @ reg! 80 opcode ! ?sign-extend ;
: mov# B0 s @ 3 lshift + rm@ + opcode ! 0ds -mrrm ;
: push# imm8? if ['] imm8, 6A else ['] imm32, 68 then dup opcode ! rm! is ?imm, ;
: test# F6 opcode ! ;
: imm-op imm! immediate-opcode ;
\ Process one operand. All operands except a direct address
\ have the stack picture ( n*x xt -addr ).
: addr? dup -addr <> ;
: op addr? if addr else drop execute then ;
\ Define instruction formats.
: instruction, opcode! opcode, ?mrrm, ?sib, ?disp, ?imm, 0asm ;
: mnemonic ( u a "name" -- ) create ['] nop 3, does> instruction, ;
: format: create ] !csp does> mnemonic ;
: immediate: ' latestxt >body ! ;
\ Instruction formats.
format: 0op -mrrm ;
format: 1reg op reg>opcode 0ds -mrrm ;
format: 1op opcode>reg op d off ;
format: 2op op op ;
format: 2op-d op op d off ;
format: 2op-ds op op 0ds ;
format: 1addr op relative -mrrm ;
format: 1imm8 !op8 op -mrrm ;
\ Instruction mnemonics.
00 2op add, immediate: alu#
08 2op or, immediate: alu#
0F44 2op-ds cmove, \ Todo: other condition codes.
0FB6 2op-ds movzx,
0FBE 2op-ds movsx,
10 2op adc, immediate: alu#
18 2op sbb, immediate: alu#
20 2op and, immediate: alu#
26 0op es,
28 2op sub, immediate: alu#
2E 0op cs,
30 2op xor, immediate: alu#
36 0op ss,
38 2op cmp, immediate: alu#
3E 0op ds,
50 1reg push, immediate: push#
58 1reg pop,
64 0op fs,
65 0op gs,
\ 70 jcc
84 2op-d test, immediate: test#
86 2op-d xchg,
88 2op mov, immediate: mov#
8D 2op-ds lea,
\ 8F/0 pop, rm
90 0op nop,
C3 0op ret,
\ C6/0 immediate mov to r/m
\ C7/0 immediate mov to r/m
CD 1imm8 int,
E8 1addr call,
E9 1addr jmp,
\ EB jmp rel8
F0 0op lock,
F2 0op rep,
F3 0op repz,
F4 0op hlt,
F5 0op cmc,
F610 1op not,
F618 1op neg,
F8 0op clc,
F9 0op stc,
FA 0op cli,
FB 0op sti,
FC 0op cld,
FD 0op std,
\ FE 0 inc rm
\ FF 1 dec rm
\ FF 2 call rm
\ FF 4 jmp rm
\ FF 6 push rm
: sp? dup 4 = ;
\ Addressing mode syntax: immediate, indirect, and displaced indirect.
: # ['] imm-op -addr ;
: ) 2drop sp? if 4 ['] idx else ['] ind then -addr 0reg 0opsize ;
: )# 2drop sp? if 4 ['] idx# else ['] ind# then -addr 0reg 0opsize ;
\ Define registers.
: reg8 create , does> @ ['] reg -addr !op8 ;
: reg16 create , does> @ ['] reg -addr !op16 ;
: reg32 create , does> @ ['] reg -addr !op32 ;
: reg: dup reg8 dup reg16 dup reg32 1+ ;
\ Register names.
0
reg: al ax eax reg: cl cx ecx reg: dl dx edx reg: bl bx ebx
reg: ah sp esp reg: ch bp ebp reg: dh si esi reg: bh di edi
drop
\ Runtime for ;CODE. CODE! is defined elsewhere.
: (;code) r> code! ;
base ! only forth definitions also assembler
\ Standard assembler entry points.
: code parse-name header, ?code, start-code ;
: ;code postpone (;code) reveal postpone [ ?csp start-code ; immediate
0asm
previous

8
samples/Forth/bitmap.frt Normal file
View File

@@ -0,0 +1,8 @@
\ Bit arrays.
: bits ( u1 -- u2 ) 7 + 3 rshift ;
: bitmap ( u "name" -- ) create bits here over erase allot
does> ( u -- a x ) over 3 rshift + 1 rot 7 and lshift ;
: bit@ ( a x -- f ) swap c@ and ;
: 1bit ( a x -- ) over c@ or swap c! ;
: 0bit ( a x -- ) invert over c@ and swap c! ;
: bit! ( f a x -- ) rot if 1bit else 0bit then ;

252
samples/Forth/core.f Normal file
View File

@@ -0,0 +1,252 @@
: immediate lastxt @ dup c@ negate swap c! ;
: \ source nip >in ! ; immediate \ Copyright 2004, 2012 Lars Brinkhoff
: char \ ( "word" -- char )
bl-word here 1+ c@ ;
: ahead here 0 , ;
: resolve here swap ! ;
: ' bl-word here find 0branch [ ahead ] exit [ resolve ] 0 ;
: postpone-nonimmediate [ ' literal , ' compile, ] literal , ;
: create dovariable_code header, reveal ;
create postponers
' postpone-nonimmediate ,
' abort ,
' , ,
: word \ ( char "<chars>string<char>" -- caddr )
drop bl-word here ;
: postpone \ ( C: "word" -- )
bl word find 1+ cells postponers + @ execute ; immediate
: unresolved \ ( C: "word" -- orig )
postpone postpone postpone ahead ; immediate
: chars \ ( n1 -- n2 )
;
: else \ ( -- ) ( C: orig1 -- orig2 )
unresolved branch swap resolve ; immediate
: if \ ( flag -- ) ( C: -- orig )
unresolved 0branch ; immediate
: then \ ( -- ) ( C: orig -- )
resolve ; immediate
: [char] \ ( "word" -- )
char postpone literal ; immediate
: (does>) lastxt @ dodoes_code over >code ! r> swap >does ! ;
: does> postpone (does>) ; immediate
: begin \ ( -- ) ( C: -- dest )
here ; immediate
: while \ ( x -- ) ( C: dest -- orig dest )
unresolved 0branch swap ; immediate
: repeat \ ( -- ) ( C: orig dest -- )
postpone branch , resolve ; immediate
: until \ ( x -- ) ( C: dest -- )
postpone 0branch , ; immediate
: recurse lastxt @ compile, ; immediate
: pad \ ( -- addr )
here 1024 + ;
: parse \ ( char "string<char>" -- addr n )
pad >r begin
source? if <source 2dup <> else 0 0 then
while
r@ c! r> 1+ >r
repeat 2drop pad r> over - ;
: ( \ ( "string<paren>" -- )
[ char ) ] literal parse 2drop ; immediate
\ TODO: If necessary, refill and keep parsing.
: string, ( addr n -- )
here over allot align swap cmove ;
: (s") ( -- addr n ) ( R: ret1 -- ret2 )
r> dup @ swap cell+ 2dup + aligned >r swap ;
create squote 128 allot
: s" ( "string<quote>" -- addr n )
state @ if
postpone (s") [char] " parse dup , string,
else
[char] " parse >r squote r@ cmove squote r>
then ; immediate
: (abort") ( ... addr n -- ) ( R: ... -- )
cr type cr abort ;
: abort" ( ... x "string<quote>" -- ) ( R: ... -- )
postpone if postpone s" postpone (abort") postpone then ; immediate
\ ----------------------------------------------------------------------
( Core words. )
\ TODO: #
\ TODO: #>
\ TODO: #s
: and ( x y -- x&y ) nand invert ;
: * 1 2>r 0 swap begin r@ while
r> r> swap 2dup dup + 2>r and if swap over + swap then dup +
repeat r> r> 2drop drop ;
\ TODO: */mod
: +loop ( -- ) ( C: nest-sys -- )
postpone (+loop) postpone 0branch , postpone unloop ; immediate
: space bl emit ;
: ?.- dup 0 < if [char] - emit negate then ;
: digit [char] 0 + emit ;
: (.) base @ /mod ?dup if recurse then digit ;
: ." ( "string<quote>" -- ) postpone s" postpone type ; immediate
: . ( x -- ) ?.- (.) space ;
: postpone-number ( caddr -- )
0 0 rot count >number dup 0= if
2drop nip
postpone (literal) postpone (literal) postpone ,
postpone literal postpone ,
else
." Undefined: " type cr abort
then ;
' postpone-number postponers cell+ !
: / ( x y -- x/y ) /mod nip ;
: 0< ( n -- flag ) 0 < ;
: 1- ( n -- n-1 ) -1 + ;
: 2! ( x1 x2 addr -- ) swap over ! cell+ ! ;
: 2* ( n -- 2n ) dup + ;
\ Kernel: 2/
: 2@ ( addr -- x1 x2 ) dup cell+ @ swap @ ;
\ Kernel: 2drop
\ Kernel: 2dup
\ TODO: 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )
\ 3 pick 3 pick ;
\ TODO: 2swap
\ TODO: <#
: abs ( n -- |n| )
dup 0< if negate then ;
\ TODO: accept
: c, ( n -- )
here c! 1 chars allot ;
: char+ ( n1 -- n2 )
1+ ;
: constant create , does> @ ;
: decimal ( -- )
10 base ! ;
: depth ( -- n )
data_stack 100 cells + 'SP @ - /cell / 2 - ;
: do ( n1 n2 -- ) ( R: -- loop-sys ) ( C: -- do-sys )
postpone 2>r here ; immediate
\ TODO: environment?
\ TODO: evaluate
\ TODO: fill
\ TODO: fm/mod )
\ TODO: hold
: j ( -- x1 ) ( R: x1 x2 x3 -- x1 x2 x3 )
'RP @ 3 cells + @ ;
\ TODO: leave
: loop ( -- ) ( C: nest-sys -- )
postpone 1 postpone (+loop)
postpone 0branch ,
postpone unloop ; immediate
: lshift begin ?dup while 1- swap dup + swap repeat ;
: rshift 1 begin over while dup + swap 1- swap repeat nip
2>r 0 1 begin r@ while
r> r> 2dup swap dup + 2>r and if swap over + swap then dup +
repeat r> r> 2drop drop ;
: max ( x y -- max[x,y] )
2dup > if drop else nip then ;
\ Kernel: min
\ TODO: mod
\ TODO: move
: (quit) ( R: ... -- )
return_stack 100 cells + 'RP !
0 'source-id ! tib ''source ! #tib ''#source !
postpone [
begin
refill
while
interpret state @ 0= if ." ok" cr then
repeat
bye ;
' (quit) ' quit >body cell+ !
\ TODO: s>d
\ TODO: sign
\ TODO: sm/rem
: spaces ( n -- )
0 do space loop ;
\ TODO: u.
: signbit ( -- n ) -1 1 rshift invert ;
: xor ( x y -- x^y ) 2dup nand >r r@ nand swap r> nand nand ;
: u< ( x y -- flag ) signbit xor swap signbit xor > ;
\ TODO: um/mod
: variable ( "word" -- )
create /cell allot ;
: ['] \ ( C: "word" -- )
' postpone literal ; immediate

252
samples/Forth/core.for Normal file
View File

@@ -0,0 +1,252 @@
: immediate lastxt @ dup c@ negate swap c! ;
: \ source nip >in ! ; immediate \ Copyright 2004, 2012 Lars Brinkhoff
: char \ ( "word" -- char )
bl-word here 1+ c@ ;
: ahead here 0 , ;
: resolve here swap ! ;
: ' bl-word here find 0branch [ ahead ] exit [ resolve ] 0 ;
: postpone-nonimmediate [ ' literal , ' compile, ] literal , ;
: create dovariable_code header, reveal ;
create postponers
' postpone-nonimmediate ,
' abort ,
' , ,
: word \ ( char "<chars>string<char>" -- caddr )
drop bl-word here ;
: postpone \ ( C: "word" -- )
bl word find 1+ cells postponers + @ execute ; immediate
: unresolved \ ( C: "word" -- orig )
postpone postpone postpone ahead ; immediate
: chars \ ( n1 -- n2 )
;
: else \ ( -- ) ( C: orig1 -- orig2 )
unresolved branch swap resolve ; immediate
: if \ ( flag -- ) ( C: -- orig )
unresolved 0branch ; immediate
: then \ ( -- ) ( C: orig -- )
resolve ; immediate
: [char] \ ( "word" -- )
char postpone literal ; immediate
: (does>) lastxt @ dodoes_code over >code ! r> swap >does ! ;
: does> postpone (does>) ; immediate
: begin \ ( -- ) ( C: -- dest )
here ; immediate
: while \ ( x -- ) ( C: dest -- orig dest )
unresolved 0branch swap ; immediate
: repeat \ ( -- ) ( C: orig dest -- )
postpone branch , resolve ; immediate
: until \ ( x -- ) ( C: dest -- )
postpone 0branch , ; immediate
: recurse lastxt @ compile, ; immediate
: pad \ ( -- addr )
here 1024 + ;
: parse \ ( char "string<char>" -- addr n )
pad >r begin
source? if <source 2dup <> else 0 0 then
while
r@ c! r> 1+ >r
repeat 2drop pad r> over - ;
: ( \ ( "string<paren>" -- )
[ char ) ] literal parse 2drop ; immediate
\ TODO: If necessary, refill and keep parsing.
: string, ( addr n -- )
here over allot align swap cmove ;
: (s") ( -- addr n ) ( R: ret1 -- ret2 )
r> dup @ swap cell+ 2dup + aligned >r swap ;
create squote 128 allot
: s" ( "string<quote>" -- addr n )
state @ if
postpone (s") [char] " parse dup , string,
else
[char] " parse >r squote r@ cmove squote r>
then ; immediate
: (abort") ( ... addr n -- ) ( R: ... -- )
cr type cr abort ;
: abort" ( ... x "string<quote>" -- ) ( R: ... -- )
postpone if postpone s" postpone (abort") postpone then ; immediate
\ ----------------------------------------------------------------------
( Core words. )
\ TODO: #
\ TODO: #>
\ TODO: #s
: and ( x y -- x&y ) nand invert ;
: * 1 2>r 0 swap begin r@ while
r> r> swap 2dup dup + 2>r and if swap over + swap then dup +
repeat r> r> 2drop drop ;
\ TODO: */mod
: +loop ( -- ) ( C: nest-sys -- )
postpone (+loop) postpone 0branch , postpone unloop ; immediate
: space bl emit ;
: ?.- dup 0 < if [char] - emit negate then ;
: digit [char] 0 + emit ;
: (.) base @ /mod ?dup if recurse then digit ;
: ." ( "string<quote>" -- ) postpone s" postpone type ; immediate
: . ( x -- ) ?.- (.) space ;
: postpone-number ( caddr -- )
0 0 rot count >number dup 0= if
2drop nip
postpone (literal) postpone (literal) postpone ,
postpone literal postpone ,
else
." Undefined: " type cr abort
then ;
' postpone-number postponers cell+ !
: / ( x y -- x/y ) /mod nip ;
: 0< ( n -- flag ) 0 < ;
: 1- ( n -- n-1 ) -1 + ;
: 2! ( x1 x2 addr -- ) swap over ! cell+ ! ;
: 2* ( n -- 2n ) dup + ;
\ Kernel: 2/
: 2@ ( addr -- x1 x2 ) dup cell+ @ swap @ ;
\ Kernel: 2drop
\ Kernel: 2dup
\ TODO: 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )
\ 3 pick 3 pick ;
\ TODO: 2swap
\ TODO: <#
: abs ( n -- |n| )
dup 0< if negate then ;
\ TODO: accept
: c, ( n -- )
here c! 1 chars allot ;
: char+ ( n1 -- n2 )
1+ ;
: constant create , does> @ ;
: decimal ( -- )
10 base ! ;
: depth ( -- n )
data_stack 100 cells + 'SP @ - /cell / 2 - ;
: do ( n1 n2 -- ) ( R: -- loop-sys ) ( C: -- do-sys )
postpone 2>r here ; immediate
\ TODO: environment?
\ TODO: evaluate
\ TODO: fill
\ TODO: fm/mod )
\ TODO: hold
: j ( -- x1 ) ( R: x1 x2 x3 -- x1 x2 x3 )
'RP @ 3 cells + @ ;
\ TODO: leave
: loop ( -- ) ( C: nest-sys -- )
postpone 1 postpone (+loop)
postpone 0branch ,
postpone unloop ; immediate
: lshift begin ?dup while 1- swap dup + swap repeat ;
: rshift 1 begin over while dup + swap 1- swap repeat nip
2>r 0 1 begin r@ while
r> r> 2dup swap dup + 2>r and if swap over + swap then dup +
repeat r> r> 2drop drop ;
: max ( x y -- max[x,y] )
2dup > if drop else nip then ;
\ Kernel: min
\ TODO: mod
\ TODO: move
: (quit) ( R: ... -- )
return_stack 100 cells + 'RP !
0 'source-id ! tib ''source ! #tib ''#source !
postpone [
begin
refill
while
interpret state @ 0= if ." ok" cr then
repeat
bye ;
' (quit) ' quit >body cell+ !
\ TODO: s>d
\ TODO: sign
\ TODO: sm/rem
: spaces ( n -- )
0 do space loop ;
\ TODO: u.
: signbit ( -- n ) -1 1 rshift invert ;
: xor ( x y -- x^y ) 2dup nand >r r@ nand swap r> nand nand ;
: u< ( x y -- flag ) signbit xor swap signbit xor > ;
\ TODO: um/mod
: variable ( "word" -- )
create /cell allot ;
: ['] \ ( C: "word" -- )
' postpone literal ; immediate

252
samples/Forth/core.fs Normal file
View File

@@ -0,0 +1,252 @@
: immediate lastxt @ dup c@ negate swap c! ;
: \ source nip >in ! ; immediate \ Copyright 2004, 2012 Lars Brinkhoff
: char \ ( "word" -- char )
bl-word here 1+ c@ ;
: ahead here 0 , ;
: resolve here swap ! ;
: ' bl-word here find 0branch [ ahead ] exit [ resolve ] 0 ;
: postpone-nonimmediate [ ' literal , ' compile, ] literal , ;
: create dovariable_code header, reveal ;
create postponers
' postpone-nonimmediate ,
' abort ,
' , ,
: word \ ( char "<chars>string<char>" -- caddr )
drop bl-word here ;
: postpone \ ( C: "word" -- )
bl word find 1+ cells postponers + @ execute ; immediate
: unresolved \ ( C: "word" -- orig )
postpone postpone postpone ahead ; immediate
: chars \ ( n1 -- n2 )
;
: else \ ( -- ) ( C: orig1 -- orig2 )
unresolved branch swap resolve ; immediate
: if \ ( flag -- ) ( C: -- orig )
unresolved 0branch ; immediate
: then \ ( -- ) ( C: orig -- )
resolve ; immediate
: [char] \ ( "word" -- )
char postpone literal ; immediate
: (does>) lastxt @ dodoes_code over >code ! r> swap >does ! ;
: does> postpone (does>) ; immediate
: begin \ ( -- ) ( C: -- dest )
here ; immediate
: while \ ( x -- ) ( C: dest -- orig dest )
unresolved 0branch swap ; immediate
: repeat \ ( -- ) ( C: orig dest -- )
postpone branch , resolve ; immediate
: until \ ( x -- ) ( C: dest -- )
postpone 0branch , ; immediate
: recurse lastxt @ compile, ; immediate
: pad \ ( -- addr )
here 1024 + ;
: parse \ ( char "string<char>" -- addr n )
pad >r begin
source? if <source 2dup <> else 0 0 then
while
r@ c! r> 1+ >r
repeat 2drop pad r> over - ;
: ( \ ( "string<paren>" -- )
[ char ) ] literal parse 2drop ; immediate
\ TODO: If necessary, refill and keep parsing.
: string, ( addr n -- )
here over allot align swap cmove ;
: (s") ( -- addr n ) ( R: ret1 -- ret2 )
r> dup @ swap cell+ 2dup + aligned >r swap ;
create squote 128 allot
: s" ( "string<quote>" -- addr n )
state @ if
postpone (s") [char] " parse dup , string,
else
[char] " parse >r squote r@ cmove squote r>
then ; immediate
: (abort") ( ... addr n -- ) ( R: ... -- )
cr type cr abort ;
: abort" ( ... x "string<quote>" -- ) ( R: ... -- )
postpone if postpone s" postpone (abort") postpone then ; immediate
\ ----------------------------------------------------------------------
( Core words. )
\ TODO: #
\ TODO: #>
\ TODO: #s
: and ( x y -- x&y ) nand invert ;
: * 1 2>r 0 swap begin r@ while
r> r> swap 2dup dup + 2>r and if swap over + swap then dup +
repeat r> r> 2drop drop ;
\ TODO: */mod
: +loop ( -- ) ( C: nest-sys -- )
postpone (+loop) postpone 0branch , postpone unloop ; immediate
: space bl emit ;
: ?.- dup 0 < if [char] - emit negate then ;
: digit [char] 0 + emit ;
: (.) base @ /mod ?dup if recurse then digit ;
: ." ( "string<quote>" -- ) postpone s" postpone type ; immediate
: . ( x -- ) ?.- (.) space ;
: postpone-number ( caddr -- )
0 0 rot count >number dup 0= if
2drop nip
postpone (literal) postpone (literal) postpone ,
postpone literal postpone ,
else
." Undefined: " type cr abort
then ;
' postpone-number postponers cell+ !
: / ( x y -- x/y ) /mod nip ;
: 0< ( n -- flag ) 0 < ;
: 1- ( n -- n-1 ) -1 + ;
: 2! ( x1 x2 addr -- ) swap over ! cell+ ! ;
: 2* ( n -- 2n ) dup + ;
\ Kernel: 2/
: 2@ ( addr -- x1 x2 ) dup cell+ @ swap @ ;
\ Kernel: 2drop
\ Kernel: 2dup
\ TODO: 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )
\ 3 pick 3 pick ;
\ TODO: 2swap
\ TODO: <#
: abs ( n -- |n| )
dup 0< if negate then ;
\ TODO: accept
: c, ( n -- )
here c! 1 chars allot ;
: char+ ( n1 -- n2 )
1+ ;
: constant create , does> @ ;
: decimal ( -- )
10 base ! ;
: depth ( -- n )
data_stack 100 cells + 'SP @ - /cell / 2 - ;
: do ( n1 n2 -- ) ( R: -- loop-sys ) ( C: -- do-sys )
postpone 2>r here ; immediate
\ TODO: environment?
\ TODO: evaluate
\ TODO: fill
\ TODO: fm/mod )
\ TODO: hold
: j ( -- x1 ) ( R: x1 x2 x3 -- x1 x2 x3 )
'RP @ 3 cells + @ ;
\ TODO: leave
: loop ( -- ) ( C: nest-sys -- )
postpone 1 postpone (+loop)
postpone 0branch ,
postpone unloop ; immediate
: lshift begin ?dup while 1- swap dup + swap repeat ;
: rshift 1 begin over while dup + swap 1- swap repeat nip
2>r 0 1 begin r@ while
r> r> 2dup swap dup + 2>r and if swap over + swap then dup +
repeat r> r> 2drop drop ;
: max ( x y -- max[x,y] )
2dup > if drop else nip then ;
\ Kernel: min
\ TODO: mod
\ TODO: move
: (quit) ( R: ... -- )
return_stack 100 cells + 'RP !
0 'source-id ! tib ''source ! #tib ''#source !
postpone [
begin
refill
while
interpret state @ 0= if ." ok" cr then
repeat
bye ;
' (quit) ' quit >body cell+ !
\ TODO: s>d
\ TODO: sign
\ TODO: sm/rem
: spaces ( n -- )
0 do space loop ;
\ TODO: u.
: signbit ( -- n ) -1 1 rshift invert ;
: xor ( x y -- x^y ) 2dup nand >r r@ nand swap r> nand nand ;
: u< ( x y -- flag ) signbit xor swap signbit xor > ;
\ TODO: um/mod
: variable ( "word" -- )
create /cell allot ;
: ['] \ ( C: "word" -- )
' postpone literal ; immediate

252
samples/Forth/core1.F Normal file
View File

@@ -0,0 +1,252 @@
: immediate lastxt @ dup c@ negate swap c! ;
: \ source nip >in ! ; immediate \ Copyright 2004, 2012 Lars Brinkhoff
: char \ ( "word" -- char )
bl-word here 1+ c@ ;
: ahead here 0 , ;
: resolve here swap ! ;
: ' bl-word here find 0branch [ ahead ] exit [ resolve ] 0 ;
: postpone-nonimmediate [ ' literal , ' compile, ] literal , ;
: create dovariable_code header, reveal ;
create postponers
' postpone-nonimmediate ,
' abort ,
' , ,
: word \ ( char "<chars>string<char>" -- caddr )
drop bl-word here ;
: postpone \ ( C: "word" -- )
bl word find 1+ cells postponers + @ execute ; immediate
: unresolved \ ( C: "word" -- orig )
postpone postpone postpone ahead ; immediate
: chars \ ( n1 -- n2 )
;
: else \ ( -- ) ( C: orig1 -- orig2 )
unresolved branch swap resolve ; immediate
: if \ ( flag -- ) ( C: -- orig )
unresolved 0branch ; immediate
: then \ ( -- ) ( C: orig -- )
resolve ; immediate
: [char] \ ( "word" -- )
char postpone literal ; immediate
: (does>) lastxt @ dodoes_code over >code ! r> swap >does ! ;
: does> postpone (does>) ; immediate
: begin \ ( -- ) ( C: -- dest )
here ; immediate
: while \ ( x -- ) ( C: dest -- orig dest )
unresolved 0branch swap ; immediate
: repeat \ ( -- ) ( C: orig dest -- )
postpone branch , resolve ; immediate
: until \ ( x -- ) ( C: dest -- )
postpone 0branch , ; immediate
: recurse lastxt @ compile, ; immediate
: pad \ ( -- addr )
here 1024 + ;
: parse \ ( char "string<char>" -- addr n )
pad >r begin
source? if <source 2dup <> else 0 0 then
while
r@ c! r> 1+ >r
repeat 2drop pad r> over - ;
: ( \ ( "string<paren>" -- )
[ char ) ] literal parse 2drop ; immediate
\ TODO: If necessary, refill and keep parsing.
: string, ( addr n -- )
here over allot align swap cmove ;
: (s") ( -- addr n ) ( R: ret1 -- ret2 )
r> dup @ swap cell+ 2dup + aligned >r swap ;
create squote 128 allot
: s" ( "string<quote>" -- addr n )
state @ if
postpone (s") [char] " parse dup , string,
else
[char] " parse >r squote r@ cmove squote r>
then ; immediate
: (abort") ( ... addr n -- ) ( R: ... -- )
cr type cr abort ;
: abort" ( ... x "string<quote>" -- ) ( R: ... -- )
postpone if postpone s" postpone (abort") postpone then ; immediate
\ ----------------------------------------------------------------------
( Core words. )
\ TODO: #
\ TODO: #>
\ TODO: #s
: and ( x y -- x&y ) nand invert ;
: * 1 2>r 0 swap begin r@ while
r> r> swap 2dup dup + 2>r and if swap over + swap then dup +
repeat r> r> 2drop drop ;
\ TODO: */mod
: +loop ( -- ) ( C: nest-sys -- )
postpone (+loop) postpone 0branch , postpone unloop ; immediate
: space bl emit ;
: ?.- dup 0 < if [char] - emit negate then ;
: digit [char] 0 + emit ;
: (.) base @ /mod ?dup if recurse then digit ;
: ." ( "string<quote>" -- ) postpone s" postpone type ; immediate
: . ( x -- ) ?.- (.) space ;
: postpone-number ( caddr -- )
0 0 rot count >number dup 0= if
2drop nip
postpone (literal) postpone (literal) postpone ,
postpone literal postpone ,
else
." Undefined: " type cr abort
then ;
' postpone-number postponers cell+ !
: / ( x y -- x/y ) /mod nip ;
: 0< ( n -- flag ) 0 < ;
: 1- ( n -- n-1 ) -1 + ;
: 2! ( x1 x2 addr -- ) swap over ! cell+ ! ;
: 2* ( n -- 2n ) dup + ;
\ Kernel: 2/
: 2@ ( addr -- x1 x2 ) dup cell+ @ swap @ ;
\ Kernel: 2drop
\ Kernel: 2dup
\ TODO: 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )
\ 3 pick 3 pick ;
\ TODO: 2swap
\ TODO: <#
: abs ( n -- |n| )
dup 0< if negate then ;
\ TODO: accept
: c, ( n -- )
here c! 1 chars allot ;
: char+ ( n1 -- n2 )
1+ ;
: constant create , does> @ ;
: decimal ( -- )
10 base ! ;
: depth ( -- n )
data_stack 100 cells + 'SP @ - /cell / 2 - ;
: do ( n1 n2 -- ) ( R: -- loop-sys ) ( C: -- do-sys )
postpone 2>r here ; immediate
\ TODO: environment?
\ TODO: evaluate
\ TODO: fill
\ TODO: fm/mod )
\ TODO: hold
: j ( -- x1 ) ( R: x1 x2 x3 -- x1 x2 x3 )
'RP @ 3 cells + @ ;
\ TODO: leave
: loop ( -- ) ( C: nest-sys -- )
postpone 1 postpone (+loop)
postpone 0branch ,
postpone unloop ; immediate
: lshift begin ?dup while 1- swap dup + swap repeat ;
: rshift 1 begin over while dup + swap 1- swap repeat nip
2>r 0 1 begin r@ while
r> r> 2dup swap dup + 2>r and if swap over + swap then dup +
repeat r> r> 2drop drop ;
: max ( x y -- max[x,y] )
2dup > if drop else nip then ;
\ Kernel: min
\ TODO: mod
\ TODO: move
: (quit) ( R: ... -- )
return_stack 100 cells + 'RP !
0 'source-id ! tib ''source ! #tib ''#source !
postpone [
begin
refill
while
interpret state @ 0= if ." ok" cr then
repeat
bye ;
' (quit) ' quit >body cell+ !
\ TODO: s>d
\ TODO: sign
\ TODO: sm/rem
: spaces ( n -- )
0 do space loop ;
\ TODO: u.
: signbit ( -- n ) -1 1 rshift invert ;
: xor ( x y -- x^y ) 2dup nand >r r@ nand swap r> nand nand ;
: u< ( x y -- flag ) signbit xor swap signbit xor > ;
\ TODO: um/mod
: variable ( "word" -- )
create /cell allot ;
: ['] \ ( C: "word" -- )
' postpone literal ; immediate

7
samples/Forth/enum.frt Normal file
View File

@@ -0,0 +1,7 @@
\ Implements ENUM.
\ Double DOES>!
: enum create 0 , does> create dup @ 1 rot +! , does> @ ;
\ But this is simpler.
: enum create 0 , does> dup @ constant 1 swap +! ;

8
samples/Forth/macros.frt Normal file
View File

@@ -0,0 +1,8 @@
\ Simplifies compiling words.
: [[ ; immediate
: '<> >in @ ' swap >in ! <> ;
: (]]) begin dup '<> while postpone postpone repeat drop ;
: ]] ['] [[ (]]) ; immediate
( Usage: : foo ]] dup * [[ ; immediate : bar 42 foo . ; )

48
samples/GLSL/recurse1.fs Normal file
View File

@@ -0,0 +1,48 @@
#version 330 core
// cross-unit recursion
void main() {}
// two-level recursion
float cbar(int);
void cfoo(float)
{
cbar(2);
}
// four-level, out of order
void CB();
void CD();
void CA() { CB(); }
void CC() { CD(); }
// high degree
void CBT();
void CDT();
void CAT() { CBT(); CBT(); CBT(); }
void CCT() { CDT(); CDT(); CBT(); }
// not recursive
void norA() {}
void norB() { norA(); }
void norC() { norA(); }
void norD() { norA(); }
void norE() { norB(); }
void norF() { norB(); }
void norG() { norE(); }
void norH() { norE(); }
void norI() { norE(); }
// not recursive, but with a call leading into a cycle if ignoring direction
void norcA() { }
void norcB() { norcA(); }
void norcC() { norcB(); }
void norcD() { norcC(); norcB(); } // head of cycle
void norcE() { norcD(); } // lead into cycle

67
samples/Golo/adapters.golo Executable file
View File

@@ -0,0 +1,67 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.Adapters
local function list_sample = |fabric| {
println(">>> list_sample()")
let carbonCopy = list[]
let conf = map[
["extends", "java.util.ArrayList"],
["overrides", map[
["*", |super, name, args| {
if name == "add" {
if args: length() == 2 {
carbonCopy: add(args: get(1))
} else {
carbonCopy: add(args: get(1), args: get(2))
}
}
return super: invokeWithArguments(args)
}
]]
]]
let list = fabric: maker(conf): newInstance()
list: add("bar")
list: add(0, "foo")
list: add("baz")
println(" list: " + list + " " + list: getClass())
println("carbonCopy: " + carbonCopy + " " + carbonCopy: getClass())
}
local function runnable_sample = |fabric| {
println(">>> runnable_sample")
let result = array[1, 2, 3]
let conf = map[
["interfaces", ["java.io.Serializable", "java.lang.Runnable"]],
["implements", map[
["run", |this| {
for (var i = 0, i < result: length(), i = i + 1) {
result: set(i, result: get(i) + 10)
}
}]
]]
]
let runner = fabric: maker(conf): newInstance()
runner: run()
println(" result: " + result: toString())
println("serializable? " + (runner oftype java.io.Serializable.class))
println(" runnable? " + (runner oftype java.lang.Runnable.class))
}
function main = |args| {
let fabric = AdapterFabric()
list_sample(fabric)
runnable_sample(fabric)
}

84
samples/Golo/async.golo Executable file
View File

@@ -0,0 +1,84 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.AsyncHelpers
import gololang.Async
import java.util.concurrent.TimeUnit
import java.util.concurrent.Executors
local function fib = |n| {
if n <= 1 {
return n
} else {
return fib(n - 1) + fib(n - 2)
}
}
function main = |args| {
let executor = newCachedThreadPool()
println("Let's do some useless asynchronous operations...")
var f = executor: enqueue({
Thread.sleep(1000_L)
return 666
})
f:
onSet(|v| -> println(">>> #slow -> " + v)):
onFail(|e| -> println(">>> #fail -> " + e))
f:
cancel(true)
f = executor: enqueue({
Thread.sleep(1000_L)
return 666
})
f:
onSet(|v| -> println(">>> #ok -> " + v)):
onFail(|e| -> println(">>> #wtf? -> " + e))
let fib_10 = promise()
let fib_20 = promise()
let fib_30 = promise()
let fib_40 = promise()
let futures = [
fib_10: future(), fib_20: future(),
fib_30: future(), fib_40: future()
]
executor: submit(-> fib_10: set(fib(10)))
executor: submit(-> fib_20: set(fib(20)))
executor: submit(-> fib_30: set(fib(30)))
executor: submit(-> fib_40: set(fib(40)))
all(futures): onSet(|results| -> println(">>> Fibs: " + results))
let truth = promise()
truth:
future():
map(|v| -> "truth=" + v):
onSet(|v| -> executor: submit(-> println(">>> (another thread) " + v))):
onSet(|v| -> println(">>> (same thread) " + v))
executor: submit({
Thread.sleep(500_L)
truth: set(42)
})
Thread.sleep(1000_L)
executor: shutdown()
executor: awaitTermination(2_L, SECONDS())
println("Bye!")
}

37
samples/Golo/augmentations.golo Executable file
View File

@@ -0,0 +1,37 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.Augmentations
import java.util.LinkedList
augment java.util.List {
function with = |this, value| {
this: add(value)
return this
}
}
augment java.util.Collection {
function doToEach = |this, func| {
foreach (element in this) {
func(element)
}
}
}
function main = |args| {
let list = LinkedList(): with("foo"): with("bar"): with("baz")
list: doToEach(|value| -> println(">>> " + value))
}

43
samples/Golo/closures.golo Executable file
View File

@@ -0,0 +1,43 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module Closures
local function sayHello = |who| -> "Hello " + who + "!"
function main = |args| {
let adder = |a, b| -> a + b
println(adder: invokeWithArguments(1, 2))
println(adder(1, 2))
let addToTen = adder: bindTo(10)
println(addToTen: invokeWithArguments(2))
println(addToTen(2))
let adding = |x| -> |y| -> adder(x, y)
let addingTen = adding(10)
println(addingTen(4))
println(adding(2)(4))
println(sayHello("Julien"))
let list = java.util.LinkedList()
let pump_it = {
list: add("I heard you say")
list: add("Hey!")
list: add("Hey!")
}
pump_it()
println(list)
}

34
samples/Golo/coin-change.golo Executable file
View File

@@ -0,0 +1,34 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module CoinChange
import java.util.LinkedList
function change = |money, coins| -> match {
when money == 0 then 1
when (money < 0) or (coins: isEmpty()) then 0
otherwise change(money - coins: head(), coins) + change(money, coins: tail())
}
function main = |args| {
let coins = LinkedList(): append(1, 2, 5, 10, 20)
println("Coins: " + coins)
println("0: " + change(0, coins))
println("1: " + change(1, coins))
println("2: " + change(2, coins))
println("10: " + change(10, coins))
println("12: " + change(12, coins))
println("6: " + change(6, coins))
}

View File

@@ -0,0 +1,55 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.CollectionLiterals
local function play_with_tuples = {
let hello = ["Hello", "world", "!"]
foreach str in hello {
print(str + " ")
}
println("")
println(hello: get(0) + "-" + hello: get(1) + "-" + hello: get(2))
println(hello: join("/"))
}
local function play_with_literals = {
let data = [
[1, 2, 3],
tuple[1, 2, 3],
array[1, 2, 3],
set[1, 2, 3, 3, 1],
map[
["a", 10],
["b", 20]
],
vector[1, 2, 3],
list[1, 2, 3]
]
data: each(|element| {
println(element: toString())
println(" type: " + element: getClass())
})
}
function main = |args| {
println(">>> Literals")
play_with_literals()
println("\n>>> Tuples")
play_with_tuples()
}

View File

@@ -0,0 +1,53 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.ContextDecorator
import gololang.Decorators
let myContext = defaultContext():
count(0):
define("entry", |this, args| {
this: count(this: count() + 1)
println("hello:" + this: count())
return args
}):
define("exit", |this, result| {
require(result >= 3, "wrong value")
println("goobye")
return result
}):
define("catcher", |this, e| {
println("Caught " + e)
throw e
}):
define("finallizer", |this| {println("do some cleanup")})
@withContext(myContext)
function foo = |a, b| {
println("Hard computation")
return a + b
}
function main = |args| {
println(foo(1,2))
println("====")
println(withContext(myContext)(|a| -> 2*a)(3))
println("====")
try {
println(foo(1, 1))
} catch (e) { }
}

83
samples/Golo/decorators.golo Executable file
View File

@@ -0,0 +1,83 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.Decorators
import java.util.LinkedList
function simple_decorator = |func| {
return |a,b| -> func(a+1,b+1)
}
@simple_decorator
function simple_adder = |x,y| -> x + y
function decorator_with_params = |param1, param2|{
return |func| {
return |a,b| -> func(a+param1,b+param2)
}
}
@decorator_with_params(10,2)
function parametrized_adder = |x,y| -> x + y
function generic_decorator = |func| {
return |args...| {
println("number of params : "+args: length())
return func: invokeWithArguments(args)
}
}
@generic_decorator
function generic_adder0 = -> 42
@generic_decorator
function generic_adder1 = |x| -> x
@generic_decorator
function generic_adder2 = |x,y| -> x + y
@generic_decorator
function generic_adder3 = |x,y,z| -> x + y + z
function list_sum_decorator = |func| {
return |this| -> func(this) - 8
}
augment java.util.List {
@list_sum_decorator
function sum = |this| {
var acc = 0
foreach elem in this {
acc = acc + elem
}
return acc
}
}
function main = |args| {
println(simple_adder(10,30))
println(parametrized_adder(10,20))
println(generic_adder0())
println(generic_adder1(42))
println(generic_adder2(20,22))
println(generic_adder3(10,12,20))
let list = LinkedList()
list: add(5)
list: add(10)
list: add(15)
list: add(20)
println(list: sum())
}

View File

@@ -0,0 +1,88 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.DynamicEvaluation
import gololang.EvaluationEnvironment
local function test_asModule = |env| {
let code =
"""
module foo
function a = -> "a!"
function b = -> "b!"
"""
let mod = env: asModule(code)
let a = fun("a", mod)
let b = fun("b", mod)
println(">>> asModule()")
println(a())
println(b())
}
local function test_anonymousModule = |env| {
let code =
"""
function a = -> "a."
function b = -> "b."
"""
let mod = env: anonymousModule(code)
let a = fun("a", mod)
let b = fun("b", mod)
println(">>> anonymousModule()")
println(a())
println(b())
}
local function test_asFunction = |env| {
let code = "return (a + b) * 2"
let f = env: asFunction(code, "a", "b")
println(">>> asFunction")
println(f(10, 20))
}
local function test_def = |env| {
let code = "|a, b| -> (a + b) * 2"
let f = env: def(code)
println(">>> def")
println(f(10, 20))
}
local function test_run = |env| {
let code = """println(">>> run")
foreach (i in range(0, 3)) {
println("w00t")
}"""
env: run(code)
}
local function test_run_map = |env| {
let code = """println(">>> run_map")
println(a)
println(b)
"""
let values = java.util.TreeMap(): add("a", 1): add("b", 2)
env: run(code, values)
}
function main = |args| {
let env = EvaluationEnvironment()
test_asModule(env)
test_anonymousModule(env)
test_asFunction(env)
test_def(env)
test_run(env)
test_run_map(env)
}

View File

@@ -0,0 +1,29 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.DynamicObjectPerson
local function mrbean = -> DynamicObject():
name("Mr Bean"):
email("mrbean@gmail.com"):
define("toString", |this| -> this: name() + " <" + this: email() + ">")
function main = |args| {
let bean = mrbean()
println(bean: toString())
bean: email("mrbean@outlook.com")
println(bean: toString())
}

34
samples/Golo/echo-args.golo Executable file
View File

@@ -0,0 +1,34 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module EchoArgs
function main = |args| {
println("With a for loop and an index:")
for (var i = 0, i < args: length(), i = i + 1) {
println(" #" + i + " -> " + args: get(i))
}
println("With a foreach loop:")
foreach arg in args {
println(" " + arg)
}
println("With a foreach over a range:")
foreach i in range(0, args: length()) {
println(" #" + i + " -> " + args: get(i))
}
}

View File

@@ -0,0 +1,31 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module sample.EnumsThreadState
import java.lang.Thread$State
function main = |args| {
# Call the enum entry like a function
let new = Thread$State.NEW()
println("name=" + new: name() + ", ordinal=" + new: ordinal())
println("-----------")
# Walk through all enum entries
foreach element in Thread$State.values() {
println("name=" + element: name() + ", ordinal=" + element: ordinal())
}
}

39
samples/Golo/fibonacci.golo Executable file
View File

@@ -0,0 +1,39 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.Fibonacci
import java.lang.System
function fib = |n| {
if n <= 1 {
return n
} else {
return fib(n - 1) + fib(n - 2)
}
}
local function run = {
let start = System.currentTimeMillis()
let result = fib(40)
let duration = System.currentTimeMillis() - start
println(">>> " + result + " (took " + duration + "ms)")
}
function main = |args| {
while true {
run()
}
}

20
samples/Golo/helloworld.golo Executable file
View File

@@ -0,0 +1,20 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module hello.World
function main = |args| {
println("Hello world!")
}

53
samples/Golo/http-server.golo Executable file
View File

@@ -0,0 +1,53 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.WebServer
import java.lang
import java.net.InetSocketAddress
import com.sun.net.httpserver
import com.sun.net.httpserver.HttpServer
function main = |args| {
let server = HttpServer.create(InetSocketAddress("localhost", 8081), 0)
server: createContext("/", |exchange| {
let headers = exchange: getResponseHeaders()
let response = StringBuilder():
append("Requested URI: "):
append(exchange: getRequestURI()):
append("\n"):
append("Current time: "):
append(java.util.Date()):
append("\n"):
toString()
headers: set("Content-Type", "text/plain")
exchange: sendResponseHeaders(200, response: length())
exchange: getResponseBody(): write(response: getBytes())
exchange: close()
})
server: createContext("/shutdown", |exchange| {
let response = "Ok, thanks, bye!"
exchange: getResponseHeaders(): set("Content-Type", "text/plain")
exchange: sendResponseHeaders(200, response: length())
exchange: getResponseBody(): write(response: getBytes())
exchange: close()
server: stop(5)
})
server: start()
println(">>> http://localhost:8081/")
}

65
samples/Golo/logdeco.golo Executable file
View File

@@ -0,0 +1,65 @@
module samples.LogDeco
function log1 = |msg| {
return |fun| {
return |args...| {
println(msg)
return fun: invokeWithArguments(args)
}
}
}
@log1("calling foo")
function foo = |a| {
println("foo got a " + a)
}
@log1("I'am a bar")
function bar = |a| -> 2*a
let sayHello = log1("Hello")
@sayHello
function baz = -> "Goodbye"
function log2 = |msgBefore| -> |msgAfter| -> |func| -> |args...| {
println(msgBefore)
let res = func: invokeWithArguments(args)
println(msgAfter)
return res
}
@log2("enter foo")("exit foo")
function spam = |a| {
println("foo: " + a)
}
function logEnterExit = |name| -> log2("# enter " + name)("# exit " + name)
@logEnterExit("bar")
function egg = { println("doing something...") }
function main = |args| {
foo("bar")
println("---")
println(bar(21))
println("---")
println(baz())
println("---")
spam("bar")
println("---")
egg()
println("---")
let strange_use = log2("hello")("goodbye")({println(":p")})
strange_use()
println("---")
log2("another")("use")(|a|{println(a)})("strange")
}

View File

@@ -0,0 +1,40 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module Matching
import java.util.LinkedList
local function data = {
let list = LinkedList()
list: add("foo@bar.com")
list: add("+33.6.11.22.33")
list: add("http://golo-lang.org/")
list: add("def foo = bar(_._) with :> T")
return list
}
local function what_it_could_be = |item| -> match {
when item: contains("@") then "an email?"
when item: startsWith("+33") then "a French phone number?"
when item: startsWith("http://") then "a website URL?"
otherwise "I have no clue, mate!"
}
function main = |args| {
foreach item in data() {
println(item + " => " + what_it_could_be(item))
}
}

24
samples/Golo/max-int.golo Executable file
View File

@@ -0,0 +1,24 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.MaxInt
local function max_int = {
return java.lang.Integer.MAX_VALUE()
}
function main = |args| {
println(max_int())
}

55
samples/Golo/memoize.golo Executable file
View File

@@ -0,0 +1,55 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.MemoizeDecorator
import gololang.Decorators
import java.lang.System
let memo = memoizer()
@memo
function fib = |n| {
if n <= 1 {
return n
} else {
return fib(n - 1) + fib(n - 2)
}
}
@memo
function foo = |n| -> n
local function run = {
let start = System.currentTimeMillis()
let result = fib(40)
let duration = System.currentTimeMillis() - start
println(">>> fib(40) = " + result + " (took " + duration + "ms)")
}
local function run2 = {
let start = System.currentTimeMillis()
let result = foo(40)
let duration = System.currentTimeMillis() - start
println(">>> foo(40) = " + result + " (took " + duration + "ms)")
}
function main = |args| {
foreach i in range(0, 5) {
println("run " + i)
run()
run2()
}
}

43
samples/Golo/null-safety.golo Executable file
View File

@@ -0,0 +1,43 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module DealingWithNull
import java.util
function main = |args| {
# Data model
let contacts = map[
["mrbean", map[
["email", "bean@gmail.com"],
["url", "http://mrbean.com"]
]],
["larry", map[
["email", "larry@iamricherthanyou.com"]
]]
]
# MrBean and Larry
let mrbean = contacts: get("mrbean")
let larry = contacts: get("larry")
# Illustrates orIfNull
println(mrbean: get("url") orIfNull "n/a")
println(larry: get("url") orIfNull "n/a")
# Querying a non-existent data model because there is no 'address' entry
println(mrbean: get("address")?: street()?: number() orIfNull "n/a")
}

View File

@@ -0,0 +1,65 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.PrepostDecorator
import gololang.Decorators
let isInteger = isOfType(Integer.class)
@checkResult(isString(): andThen(lengthIs(2)))
@checkArguments(isInteger: andThen(isPositive()), isString())
function foo = |a, b| {
return b + a
}
let myCheck = checkArguments(isInteger: andThen(isPositive()))
@myCheck
function inv = |v| -> 1.0 / v
let isPositiveInt = isInteger: andThen(isPositive())
@checkArguments(isPositiveInt)
function mul = |v| -> 10 * v
@checkArguments(isNumber())
function num = |v| -> "ok"
@checkArguments(isNotNull())
function notnull = |v| -> "ok"
function main = |args| {
try { println(foo(1, "b")) } catch (e) { println(e) }
try { println(foo(-1, "b")) } catch (e) { println(e) }
try { println(foo("a", 2)) } catch (e) { println(e) }
try { println(foo(1, 2)) } catch (e) { println(e) }
try { println(foo(10, "ab")) } catch (e) { println(e) }
try { println(inv(10)) } catch (e) { println(e) }
try { println(inv(0)) } catch (e) { println(e) }
try { println(mul(5)) } catch (e) { println(e) }
try { println(mul(0)) } catch (e) { println(e) }
try { println(num(1)) } catch (e) { println(e) }
try { println(num(1_L)) } catch (e) { println(e) }
try { println(num(1.5)) } catch (e) { println(e) }
try { println(num(1.5_F)) } catch (e) { println(e) }
try { println(num("a")) } catch (e) { println(e) }
try { println(num('a')) } catch (e) { println(e) }
try { println(notnull('1')) } catch (e) { println(e) }
try { println(notnull(null)) } catch (e) { println(e) }
}

69
samples/Golo/structs.golo Executable file
View File

@@ -0,0 +1,69 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module StructDemo
struct Point = { x, y }
augment StructDemo.types.Point {
function move = |this, offsetX, offsetY| {
this: x(this: x() + offsetX)
this: y(this: y() + offsetY)
return this
}
function relative = |this, offsetX, offsetY| -> Point(this: x() + offsetX, this: y() + offsetY)
}
function main = |args| {
let p1 = Point(1, 2)
let p2 = Point(): x(1): y(2)
let p3 = p1: frozenCopy()
let p4 = p1: frozenCopy()
println(p1)
println("x = " + p1: x())
println("y = " + p1: y())
println("p1 == p2 " + (p1 == p2))
println("p1 == p3 " + (p1 == p3))
println("p3 == p4 " + (p3 == p4))
println("#p1 " + p1: hashCode())
println("#p2 " + p2: hashCode())
println("#p3 " + p3: hashCode())
println("#p4 " + p4: hashCode())
println("p1: members() " + p1: members())
println("p1: values() " + p1: values())
foreach item in p1 {
println(item: get(0) + " -> " + item: get(1))
}
println("p1: set(\"x\", 10) " + p1: set("x", 10))
println("p1: move(10, 5) " + p1: move(10, 5))
println("p1: relative(11, 6) " + p1: relative(11, 6))
let p5 = ImmutablePoint(10, 20)
println("p5: " + p5)
try {
p5: x(100)
} catch (expected) {
println("p5 is immutable, so... " + expected: getMessage())
}
}

View File

@@ -0,0 +1,43 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.SwingActionListener
import java.awt.event
import javax.swing
import javax.swing.WindowConstants
local function listener = |handler| -> asInterfaceInstance(ActionListener.class, handler)
function main = |args| {
let frame = JFrame("Action listeners")
frame: setDefaultCloseOperation(EXIT_ON_CLOSE())
let button = JButton("Click me!")
button: setFont(button: getFont(): deriveFont(96.0_F))
# Using a helper function
button: addActionListener(listener(|event| -> println("Clicked!")))
# Using a standard augmentation: MethodHandle::to(Class)
button: addActionListener((|event| -> println("[click]")): to(ActionListener.class))
# Straight closure passing
button: addActionListener(|event| -> println("( )"))
frame: getContentPane(): add(button)
frame: pack()
frame: setVisible(true)
}

View File

@@ -0,0 +1,31 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.SwingHelloWorld
import javax.swing
import javax.swing.WindowConstants
function main = |args| {
let frame = JFrame("Hello world")
frame: setDefaultCloseOperation(EXIT_ON_CLOSE())
let label = JLabel("Hello world")
label: setFont(label: getFont(): deriveFont(128.0_F))
frame: getContentPane(): add(label)
frame: pack()
frame: setVisible(true)
}

View File

@@ -0,0 +1,90 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module samples.TemplatesChatWebapp
import java.lang
import java.io
import java.net.InetSocketAddress
import com.sun.net.httpserver
import com.sun.net.httpserver.HttpServer
local function redirect = |exchange, to| {
exchange: getResponseHeaders(): set("Location", to)
exchange: sendResponseHeaders(303, 0)
exchange: close()
}
local function respond = |exchange, body| {
exchange: getResponseHeaders(): set("Content-Type", "text/html")
exchange: sendResponseHeaders(200, body: length())
exchange: getResponseBody(): write(body: getBytes())
exchange: close()
}
# This is leaky and works with just 1 POST parameter...
local function extract_post = |exchange, posts| {
let reader = BufferedReader(InputStreamReader(exchange: getRequestBody()))
var line = reader: readLine()
while line isnt null {
if line: startsWith("msg=") {
posts: add(java.net.URLDecoder.decode(line: substring(4), "UTF-8"))
}
line = reader: readLine()
}
reader: close()
}
local function index = |posts, template, exchange| {
if exchange: getRequestMethod() == "POST" {
extract_post(exchange, posts)
redirect(exchange, "/")
} else {
respond(exchange, template(posts))
}
}
local function index_template = -> """
<%@params posts %>
<!DOCTYPE html>
<html>
<head>
<title>Golo Chat</title>
</head>
<body>
<form action="/" method="post">
<input type="text" name="msg">
<input type="submit" value="Send">
</form>
<div>
<h3>Last posts</h3>
<% foreach post in posts { %>
<div>
<%= post %>
</div>
<% } %>
</div>
</body>
</html>
"""
function main = |args| {
let index_tpl = gololang.TemplateEngine(): compile(index_template())
let posts = java.util.concurrent.ConcurrentLinkedDeque()
let server = HttpServer.create(InetSocketAddress("localhost", 8081), 0)
server: createContext("/", ^index: bindTo(posts): bindTo(index_tpl))
server: start()
println(">>> http://localhost:8081/")
}

View File

@@ -0,0 +1,51 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module MoreCoolContainers
function main = |args| {
println(">>> DynamicVariable")
let dyn = DynamicVariable("Foo")
println(dyn: value())
let t1 = Thread({
dyn: withValue(666, {
println(dyn: value())
})
})
let t2 = Thread({
dyn: withValue(69, {
println(dyn: value())
})
})
t1: start()
t2: start()
t1: join()
t2: join()
println(dyn: value())
println(">>> Observable")
let foo = Observable("Foo")
foo: onChange(|v| -> println("foo = " + v))
let mapped = foo: map(|v| -> v + "!")
mapped: onChange(|v| -> println("mapped = " + v))
foo: set("69")
}

48
samples/Golo/workers.golo Executable file
View File

@@ -0,0 +1,48 @@
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module Workers
import java.lang.Thread
import java.util.concurrent
import gololang.concurrent.workers.WorkerEnvironment
local function pusher = |queue, message| -> queue: offer(message)
local function generator = |port, message| {
foreach i in range(0, 100) {
port: send(message)
}
}
function main = |args| {
let env = WorkerEnvironment.builder(): withFixedThreadPool()
let queue = ConcurrentLinkedQueue()
let pusherPort = env: spawn(^pusher: bindTo(queue))
let generatorPort = env: spawn(^generator: bindTo(pusherPort))
let finishPort = env: spawn(|any| -> env: shutdown())
foreach i in range(0, 10) {
generatorPort: send("[" + i + "]")
}
Thread.sleep(2000_L)
finishPort: send("Die!")
env: awaitTermination(2000)
println(queue: reduce("", |acc, next| -> acc + " " + next))
}

238
samples/Gosu/Ronin.gs Normal file
View File

@@ -0,0 +1,238 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
package ronin
uses gw.util.concurrent.LockingLazyVar
uses gw.lang.reflect.*
uses java.lang.*
uses java.io.*
uses ronin.config.*
uses org.slf4j.*
/**
* The central location for Ronin utility methods. Controllers and templates should generally access the
* methods and properties they inherit from {@link ronin.IRoninUtils} instead of using the methods and
* properties here.
*/
class Ronin {
// One static field to rule the all...
static var _CONFIG : IRoninConfig as Config
// And one thread local to bind them
static var _CURRENT_REQUEST = new ThreadLocal<RoninRequest>();
// That's inconstructable
private construct() {}
internal static function init(servlet : RoninServlet, m : ApplicationMode, src : File) {
if(_CONFIG != null) {
throw "Cannot initialize a Ronin application multiple times!"
}
var cfg = TypeSystem.getByFullNameIfValid("config.RoninConfig")
var defaultWarning = false
if(cfg != null) {
var ctor = cfg.TypeInfo.getConstructor({ronin.config.ApplicationMode, ronin.RoninServlet})
if(ctor == null) {
throw "config.RoninConfig must have a constructor with the same signature as ronin.config.RoninConfig"
}
_CONFIG = ctor.Constructor.newInstance({m, servlet}) as IRoninConfig
} else {
_CONFIG = new DefaultRoninConfig(m, servlet)
defaultWarning = true
}
var roninLogger = TypeSystem.getByFullNameIfValid("ronin.RoninLoggerFactory")
if(roninLogger != null) {
roninLogger.TypeInfo.getMethod("init", {ronin.config.LogLevel}).CallHandler.handleCall(null, {LogLevel})
}
if(defaultWarning) {
log("No configuration was found at config.RoninConfig, using the default configuration...", :level=WARN)
}
Quartz.maybeStart()
ReloadManager.setSourceRoot(src)
}
internal static property set CurrentRequest(req : RoninRequest) {
_CURRENT_REQUEST.set(req)
}
//============================================
// Public API
//============================================
/**
* The trace handler for the current request.
*/
static property get CurrentTrace() : Trace {
return CurrentRequest?.Trace
}
/**
* Ronin's representation of the current request.
*/
static property get CurrentRequest() : RoninRequest {
return _CURRENT_REQUEST.get()
}
/**
* The mode in which this application is running.
*/
static property get Mode() : ApplicationMode {
return _CONFIG?.Mode ?: TESTING
}
/**
* The log level at and above which log messages should be displayed.
*/
static property get LogLevel() : LogLevel {
return _CONFIG?.LogLevel ?: DEBUG
}
/**
* Whether or not to display detailed trace information on each request.
*/
static property get TraceEnabled() : boolean {
return _CONFIG != null ? _CONFIG.TraceEnabled : true
}
/**
* The default controller method to call when no method name is present in the request URL.
*/
static property get DefaultAction() : String {
return _CONFIG?.DefaultAction
}
/**
* The default controller to call when no controller name is present in the request URL.
*/
static property get DefaultController() : Type {
return _CONFIG?.DefaultController
}
/**
* The servlet responsible for handling Ronin requests.
*/
static property get RoninServlet() : RoninServlet {
return _CONFIG?.RoninServlet
}
/**
* The handler for request processing errors.
*/
static property get ErrorHandler() : IErrorHandler {
return _CONFIG?.ErrorHandler
}
/**
* The custom handler for logging messages.
*/
static property get LogHandler() : ILogHandler {
return _CONFIG?.LogHandler
}
/**
* Logs a message using the configured log handler.
* @param msg The text of the message to log, or a block which returns said text.
* @param level (Optional) The level at which to log the message.
* @param component (Optional) The logical component from whence the message originated.
* @param exception (Optional) An exception to associate with the message.
*/
static function log(msg : Object, level : LogLevel = null, component : String = null, exception : java.lang.Throwable = null) {
if(level == null) {
level = INFO
}
if(LogLevel <= level) {
var msgStr : String
if(msg typeis block():String) {
msgStr = (msg as block():String)()
} else {
msgStr = msg as String
}
if(_CONFIG?.LogHandler != null) {
_CONFIG.LogHandler.log(msgStr, level, component, exception)
} else {
switch(level) {
case TRACE:
LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).trace(msgStr, exception)
break
case DEBUG:
LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).debug(msgStr, exception)
break
case INFO:
LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).info(msgStr, exception)
break
case WARN:
LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).warn(msgStr, exception)
break
case ERROR:
case FATAL:
LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).error(msgStr, exception)
break
}
}
}
}
/**
* The caches known to Ronin.
*/
static enum CacheStore {
REQUEST,
SESSION,
APPLICATION
}
/**
* Retrieves a value from a cache, or computes and stores it if it is not in the cache.
* @param value A block which will compute the desired value.
* @param name (Optional) A unique identifier for the value. Default is null, which means one will be
* generated from the type of the value.
* @param store (Optional) The cache store used to retrieve or store the value. Default is the request cache.
* @return The retrieved or computed value.
*/
static function cache<T>(value : block():T, name : String = null, store : CacheStore = null) : T {
if(store == null or store == REQUEST) {
return _CONFIG.RequestCache.getValue(value, name)
} else if (store == SESSION) {
return _CONFIG.SessionCache.getValue(value, name)
} else if (store == APPLICATION) {
return _CONFIG.ApplicationCache.getValue(value, name)
} else {
throw "Don't know about CacheStore ${store}"
}
}
/**
* Invalidates a cached value in a cache.
* @param name The unique identifier for the value.
* @param store The cache store in which to invalidate the value.
*/
static function invalidate<T>(name : String, store : CacheStore) {
if(store == null or store == REQUEST) {
_CONFIG.RequestCache.invalidate(name)
} else if (store == SESSION) {
_CONFIG.SessionCache.invalidate(name)
} else if (store == APPLICATION) {
_CONFIG.ApplicationCache.invalidate(name)
} else {
throw "Don't know about CacheStore ${store}"
}
}
/**
* Detects changes made to resources in the Ronin application and
* reloads them. This function should only be called when Ronin is
* in development mode.
*/
static function loadChanges() {
ReloadManager.detectAndReloadChangedResources()
}
}

View File

@@ -0,0 +1,18 @@
apply plugin: GreetingPlugin
greeting.message = 'Hi from Gradle'
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
// Add the 'greeting' extension object
project.extensions.create("greeting", GreetingPluginExtension)
// Add a task that uses the configuration
project.task('hello') << {
println project.greeting.message
}
}
}
class GreetingPluginExtension {
def String message = 'Hello from GreetingPlugin'
}

View File

@@ -0,0 +1,20 @@
apply plugin: GreetingPlugin
greeting {
message = 'Hi'
greeter = 'Gradle'
}
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("greeting", GreetingPluginExtension)
project.task('hello') << {
println "${project.greeting.message} from ${project.greeting.greeter}"
}
}
}
class GreetingPluginExtension {
String message
String greeter
}

View File

@@ -0,0 +1,21 @@
graph
[
directed 0
node
[
id 0
label "Node 1"
value 100
]
node
[
id 1
label "Node 2"
value 200
]
edge
[
source 1
target 0
]
]

View File

@@ -0,0 +1,50 @@
/*
Huffman Tree DOT graph.
DOT Reference : http://www.graphviz.org/doc/info/lang.html
http://en.wikipedia.org/wiki/DOT_language
Timestamp : 1415989074
Phrase : 'OH GOD WHY IS LINGUIST SO ANAL ABOUT THIS STUFF'
Generated on http://huffman.ooz.ie/
*/
digraph G {
edge [label=0];
graph [ranksep=0];
T [shape=record, label="{{T|4}|000}"];
S [shape=record, label="{{S|5}|001}"];
SPACE [shape=record, label="{{SPACE|9}|01}"];
A [shape=record, label="{{A|3}|1000}"];
H [shape=record, label="{{H|3}|1001}"];
U [shape=record, label="{{U|3}|1010}"];
L [shape=record, label="{{L|2}|10110}"];
N [shape=record, label="{{N|2}|10111}"];
I [shape=record, label="{{I|4}|1100}"];
O [shape=record, label="{{O|4}|1101}"];
G [shape=record, label="{{G|2}|11100}"];
F [shape=record, label="{{F|2}|11101}"];
GF [label=4];
W [shape=record, label="{{W|1}|111100}"];
Y [shape=record, label="{{Y|1}|111101}"];
B [shape=record, label="{{B|1}|111110}"];
D [shape=record, label="{{D|1}|111111}"];
BD [label=2];
WYBD [label=4];
GFWYBD [label=8];
47 -> 18 -> 9 -> T;
29 -> 13 -> 6 -> A;
7 -> U;
4 -> L;
16 -> 8 -> I;
GFWYBD -> GF -> G;
WYBD -> 2 -> W;
BD -> B;9 -> S [label=1];
18 -> SPACE [label=1];
6 -> H [label=1];
13 -> 7 -> 4 -> N [label=1];
8 -> O [label=1];
GF -> F [label=1];
2 -> Y [label=1];
47 -> 29 -> 16 -> GFWYBD -> WYBD -> BD -> D [label=1];
}

View File

@@ -0,0 +1,74 @@
/*
Huffman Tree DOT graph.
DOT Reference : http://www.graphviz.org/doc/info/lang.html
http://en.wikipedia.org/wiki/DOT_language
Timestamp : 1415988139
Phrase : 'SERIAL KILLER AND SEX OFFENDER ANGUS SINCLAIR IS JAILED FOR A MINIMUM OF 37 YEARS FOR THE 1977 WORLDS END MURDERS OF HELEN SCOTT AND CHRISTINE EADIE.'
Generated on http://huffman.ooz.ie/
*/
digraph G {
edge [label=0];
graph [ranksep=0];
node [shape=record];
U [label="{{U|3}|00000}"];
G [label="{{G|1}|0000100}"];
K [label="{{K|1}|0000101}"];
_3 [label="{{3|1}|0000110}"];
_9 [label="{{9|1}|0000111}"];
_39 [label=2];
L [label="{{L|7}|0001}"];
O [label="{{O|7}|0010}"];
Y [label="{{Y|1}|0011000}"];
X [label="{{X|1}|0011001}"];
YX [label=2];
J [label="{{J|1}|0011010}"];
W [label="{{W|1}|0011011}"];
JW [label=2];
YXJW [label=4];
M [label="{{M|4}|00111}"];
E [label="{{E|15}|010}"];
D [label="{{D|8}|0110}"];
T [label="{{T|4}|01110}"];
DOT [label="{{DOT|1}|0111100}"];
_1 [label="{{1|1}|0111101}"];
DOT1 [label=2];
_7 [label="{{7|3}|011111}"];
A [label="{{A|9}|1000}"];
N [label="{{N|9}|1001}"];
S [label="{{S|10}|1010}"];
I [label="{{I|11}|1011}"];
R [label="{{R|11}|1100}"];
C [label="{{C|3}|110100}"];
H [label="{{H|3}|110101}"];
F [label="{{F|6}|11011}"];
SPACE [label="{{SPACE|26}|111}"];
149 -> 61 -> 29 -> 14 -> 7 -> U;
4 -> 2 -> G;
_39 -> _3;
15 -> O;
8 -> YXJW -> YX -> Y;
JW -> J;
32 -> E;
17 -> D;
9 -> T;
5 -> DOT1 -> DOT;
88 -> 39 -> 18 -> A;
21 -> S;
49 -> 23 -> R;
12 -> 6 -> C;2 -> K [label=1];
7 -> 4 -> _39 -> _9 [label=1];
14 -> L [label=1];
YX -> X [label=1];
YXJW -> JW -> W [label=1];
29 -> 15 -> 8 -> M [label=1];
DOT1 -> _1 [label=1];
61 -> 32 -> 17 -> 9 -> 5 -> _7 [label=1];
18 -> N [label=1];
39 -> 21 -> I [label=1];
6 -> H [label=1];
23 -> 12 -> F [label=1];
149 -> 88 -> 49 -> SPACE [label=1];
}

17
samples/HTML/example.xht Normal file
View File

@@ -0,0 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>This is a XHTML sample file</title>
<style type="text/css"><![CDATA[
#example {
background-color: yellow;
}
]]></style>
</head>
<body>
<div id="example">
Just a simple <strong>XHTML</strong> test page.
</div>
</body>
</html>

55
samples/Hack/Assert.hh Normal file
View File

@@ -0,0 +1,55 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
final class AssertException extends Exception {}
final class Assert {
public static function isNum(mixed $x): num {
if (is_float($x)) {
return $x;
} else if (is_int($x)) {
return $x;
}
throw new AssertException('Expected an int or float value');
}
public static function isInt(mixed $x): int {
if (is_int($x)) {
return $x;
}
throw new AssertException('Expected an int');
}
public static function isFloat(mixed $x): float {
if (is_float($x)) {
return $x;
}
throw new AssertException('Expected a float');
}
public static function isString(mixed $x): string {
if (is_string($x)) {
return $x;
}
throw new AssertException('Expected a string');
}
// For arrays you need to check every element
public static function isArrayOf<T>(
(function(mixed): T) $fn,
mixed $x,
): array<T> {
if (is_array($x)) {
return array_map($fn, $x);
}
throw new AssertException('Expected an array');
}
}

View File

@@ -0,0 +1,52 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/recipe/init.php';
require_once "demo.php";
class AssertRecipe extends Recipe implements RecipeWithDemo {
protected function getName(): string {
return 'Assert';
}
<<Override>>
protected function getDescription(): ?string {
return 'When you have values with unknown types, it is useful to make '.
'some runtime assertions and have the type checker understand. This '.
'recipe demonstrates one approach.';
}
protected function getFilenames(): Vector<string> {
return Vector {
'Assert.php',
};
}
protected function getDocs(): Vector<(string, string)> {
return Vector{
tuple ('Mixed Types', 'hack.annotations.mixedtypes'),
tuple ('Type Inference', 'hack.otherrulesandfeatures.typeinference'),
};
}
public function getDemoFilename(): string {
return 'demo.php';
}
public function getDemoResult(): string {
return assert_main();
}
public function getDemoXHP(): ?:xhp {
return null;
}
}

View File

@@ -0,0 +1,39 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
require_once $_SERVER['DOCUMENT_ROOT'].'/core/startup/init.php';
abstract class Controller {
protected function __construct() {
startup();
}
abstract protected function getCSS(): Set<string>;
abstract protected function getJS(): Set<string>;
abstract protected function getTitle(): string;
abstract protected function render(): :xhp;
final protected function getHead(): :xhp {
$css = $this->getCSS()->toVector()->map(
($css) ==> <link rel="stylesheet" type="text/css" href={$css} />
);
$js = $this->getJS()->toVector()->map(
($js) ==> <script src={$js} />
);
return
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>{$this->getTitle()}</title>
{$css->toArray()}
{$js->toArray()}
</head>;
}
}

View File

@@ -0,0 +1,52 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/recipe/init.php';
require_once "demo.php";
class DBResultRecipe extends Recipe implements RecipeWithDemo {
protected function getName(): string {
return 'DB Result';
}
<<Override>>
protected function getDescription(): ?string {
return 'Fetching data from a DB introduces a few typing challenges. '.
'First, the data comes back untyped. Second, a row in a DB generally '.
'contains columns of different types.';
}
protected function getFilenames(): Vector<string> {
return Vector {
'FakeDB.php',
};
}
protected function getDocs(): Vector<(string, string)> {
return Vector{
tuple ('Hack Shapes', 'hack.shapes'),
tuple ('Mixed Types', 'hack.annotations.mixedtypes'),
};
}
public function getDemoFilename(): string {
return 'demo.php';
}
public function getDemoResult(): string {
return db_result_main();
}
public function getDemoXHP(): ?:xhp {
return null;
}
}

View File

@@ -0,0 +1,22 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
require_once $_SERVER['DOCUMENT_ROOT'].'/vendor/hhvm/xhp/src/init.php';
final class :documentation extends :x:element {
attribute string name;
protected function render(): :xhp {
$name = implode('.', explode(' ', $this->getAttribute('name'))).".php";
$href = "http://hhvm.com/manual/en/$name";
return <a class="docs button" href={$href} target="_blank">docs &rarr;</a>;
}
}

65
samples/Hack/FakeDB.hh Normal file
View File

@@ -0,0 +1,65 @@
<?hh // strict
type DBResultExtra = shape('age' => int);
type DBResult = shape(
'id' => int,
'name' => string,
'extra' => DBResultExtra,
);
final class FakeDB {
public function getRawRows(): array<array<string, mixed>> {
$good_extra = json_encode(array('age' => 40));
$bad_extra = 'corrupt data';
// Real code would query a DB, but for now let's hardcode it
return array(
array(
'id' => 123,
'name' => 'Alice',
'extra' => $good_extra,
),
array(
'id' => 456,
'name' => 'Bob',
'extra' => $bad_extra,
),
);
}
/**
* When processing untyped data you need to check each piece of data and
* figure out whether to give up or recover when the data is bad
*/
public function processRow(array<string, mixed> $row): ?DBResult {
$row = Map::fromArray($row);
$id = $row->contains('id') ? $row['id'] : null;
$name = $row->contains('name') ? $row['name'] : null;
$extra = $row->contains('extra') ? json_decode($row['extra'], true) : null;
// Ignore rows with invalid IDs or names
if (!is_int($id) || !is_string($name)) {
return null;
}
// Try to recover from a bad extra column
if (!is_array($extra)) {
$extra = shape('age' => 0);
} else {
$extra = Map::fromArray($extra);
$extra = shape('age' => $extra->contains('age') ? $extra['age'] : 0);
}
return shape('id' => $id, 'name' => $name, 'extra' => $extra);
}
public function getDBResults(): Vector<DBResult> {
$ret = Vector {};
foreach ($this->getRawRows() as $raw_row) {
$row = $this->processRow($raw_row);
if ($row !== null) {
$ret->add($row);
}
}
return $ret;
}
}

View File

@@ -0,0 +1,72 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/recipe/init.php';
require_once "demo.php";
class GetAndPostRecipe extends Recipe implements RecipeWithDemo {
protected function getName(): string {
return '$_GET and $_POST';
}
<<Override>>
protected function getDescription(): ?string {
return 'A small example of how to interact with superglobals and the '.
'untyped data they can contain.';
}
protected function getFilenames(): Vector<string> {
return Vector {
'NonStrictFile.php',
'StrictFile.php',
};
}
protected function getDocs(): Vector<(string, string)> {
return Vector {
tuple('invariant()', 'hack.otherrulesandfeatures.invariant'),
};
}
public function getDemoFilename(): string {
return 'demo.php';
}
public function getDemoResult(): string {
return get_and_post_main();
}
public function getDemoXHP(): :xhp {
$url = '/recipes/get-and-post/';
return
<x:frag>
<div>
<a href={"$url?myIntParam=8675309#demo"} class="button">GET myIntParam=8675309</a>
</div>
<div>
<a href={"$url?myIntParam=boom#demo"} class="button">GET myIntParam=boom</a>
</div>
<div>
<form action={"$url#demo"} method="post">
<input type="hidden" name="myIntParam" value="5551234"/>
<input type="submit" class="button" value="POST myIntParam=5551234"/>
</form>
</div>
<div>
<form action={"$url#demo"} method="post">
<input type="hidden" name="myIntParam" value="boom"/>
<input type="submit" class="button" value="POST myIntParam=boom"/>
</form>
</div>
</x:frag>;
}
}

View File

@@ -0,0 +1,30 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
abstract class GetController extends Controller {
final protected function __construct(private Request $request) {
parent::__construct();
}
final protected function getRequest(): Request {
return $this->request;
}
final public function go(array<mixed, mixed> $get): void {
$request = new Request(Map::fromArray($get));
$controller = new static($request);
echo "<!DOCTYPE html>";
$head = $controller->getHead();
$body = $controller->render();
echo (string)$head;
echo (string)$body;
}
}

View File

@@ -0,0 +1,38 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/init.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/standard-page/init.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/vendor/hhvm/xhp/src/init.php';
class HomeController extends GetController {
use StandardPage;
protected function getTitle(): string {
return 'Hack Cookbook';
}
protected function renderMainColumn(): :xhp {
return <div>
<h1>Cookbook</h1>
<p>
The Hack Cookbook helps you write Hack code by giving you examples of
Hack code. It is written in Hack and is open source. If you
<a href="http://github.com/facebook/hack-example-site">
head over to GitHub,
</a>
you can read the code, check out the repository, and run it
yourself. The recipes in this cookbook are small examples that
illustrate how to use Hack to solve common and interesting problems.
</p>
</div>;
}
}

View File

@@ -0,0 +1,13 @@
<?hh // strict
require_once $_SERVER['DOCUMENT_ROOT'].'/core/funs/init.php';
final class MySecureRequest {
public function __construct(private Map<string, mixed> $GETParams) {}
public function stringParam(string $name): UNESCAPED_STRING {
invariant($this->GETParams->contains($name), 'Unknown GET param: '.$name);
$raw_string = $this->GETParams[$name];
invariant(is_string($raw_string), $name.' is not a string');
return unescaped_string($raw_string);
}
}

104
samples/Hack/Nav.hh Normal file
View File

@@ -0,0 +1,104 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
require_once $_SERVER['DOCUMENT_ROOT'].'/vendor/hhvm/xhp/src/init.php';
type NavItem = shape(
'name' => string,
'location' => string,
);
type NavSection = shape(
'name' => string,
'location' => ?string,
'items' => Vector<NavItem>,
);
final class :hack:nav extends :x:element {
private function getNavSections(): Vector<NavSection> {
return Vector{
shape(
'name' => 'Home',
'location' => '/',
'items' => Vector {},
),
shape(
'name' => 'GitHub',
'location' => 'http://github.com/facebook/hack-example-site',
'items' => Vector {},
),
shape(
'name' => 'Recipes',
'location' => null,
'items' => Vector {
shape(
'name' => '$_GET and $_POST',
'location' => '/recipes/get-and-post/',
),
shape(
'name' => 'Assert',
'location' => '/recipes/assert/',
),
shape(
'name' => 'DB Result',
'location' => '/recipes/db-result/',
),
shape(
'name' => 'Unescaped String',
'location' => '/recipes/unescaped-string/',
),
shape(
'name' => 'User ID',
'location' => '/recipes/user-id/',
),
},
),
};
}
private function renderNavItems(Vector<NavItem> $items): :xhp {
$render_item = $item ==>
<li>
<a class="navItem" href={$item['location']}>
{$item['name']}
</a>
</li>;
return
<x:frag>
{$items->map($render_item)->toArray()}
</x:frag>;
}
private function renderNavSection(NavSection $section): :xhp {
$section_item = <h3 class="navItem">{$section['name']}</h3>;
if ($section['location'] !== null) {
$section_item = <a href={$section['location']}>{$section_item}</a>;
}
return
<li class="navSectionItem">
{$section_item}
<ul class="navItems">
{$this->renderNavItems($section['items'])}
</ul>
</li>;
}
public function render(): :xhp {
$sections = $this->getNavSections()
->map($section ==> $this->renderNavSection($section));
return
<div class="nav">
<ul class="navSections">
{$sections->toArray()}
</ul>
</div>;
}
}

View File

@@ -0,0 +1,27 @@
<?hh
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
function getGETParams(): Map<string, mixed> {
// $_GET is not defined in code so Hack doesn't know about it and you can't
// use it in strict mode. You can interact with it outside of strict mode,
// though.
return Map::fromArray($_GET);
}
function getPOSTParams(): Map<string, mixed> {
// Same deal with $_POST and other magically defined globals
return Map::fromArray($_POST);
}
// Same deal with $_SERVER
function isGET(): bool {
return $_SERVER['REQUEST_METHOD'] === 'GET';
}

93
samples/Hack/Recipe.hh Normal file
View File

@@ -0,0 +1,93 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/init.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/standard-page/init.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/core/myxhp/init.php';
abstract class Recipe extends GetController {
use StandardPage;
abstract protected function getName(): string;
abstract protected function getFilenames(): Vector<string>;
abstract protected function getDocs(): Vector<(string, string)>;
protected function getDescription(): ?string {
return null;
}
final protected function getTitle(): string {
return $this->getName().' - Hack Cookbook';
}
final protected function renderMainColumn(): :xhp {
$main_column =
<x:frag>
<h1>{$this->getName()}</h1>
</x:frag>;
$description = $this->getDescription();
if ($description !== null) {
$main_column->appendChild(<p>{$description}</p>);
}
foreach ($this->getFilenames() as $filename) {
$file =
<div class="file">
<div class="filename">{$filename}</div>
<phpfile filename={$filename}/>
</div>;
$main_column->appendChild($file);
}
$recipe = $this;
if ($recipe instanceof RecipeWithDemo) {
try {
$result = $recipe->getDemoResult();
} catch (Exception $e) {
$result = sprintf(
"Demo threw an %s:\n%s",
get_class($e),
$e->getMessage(),
);
}
$result = explode("\n", trim($result));
$result = array_map($x ==> <x:frag>{$x}<br/></x:frag>, $result);
$demo =
<x:frag>
<div class="demo" id="demo">
<h3>Demo</h3>
{$recipe->getDemoXHP()}
<div class="filename">{$recipe->getDemoFilename()}</div>
<phpfile filename={$recipe->getDemoFilename()}/>
<div class="filename">Output</div>
<div class="demoResult">
{$result}
</div>
</div>
</x:frag>;
$main_column->appendChild($demo);
}
if (!$this->getDocs()->isEmpty()) {
$render_doc_link = function($doc) {
list($name, $link) = $doc;
$link = "http://hhvm.com/manual/en/$link.php";
return <li><a href={$link}>{$name}</a></li>;
};
$main_column->appendChild(
<div class="docs">
<h3>Relevant Official Documentation</h3>
<ul>
{$this->getDocs()->map($render_doc_link)->toArray()}
</ul>
</div>
);
}
return $main_column;
}
}

View File

@@ -0,0 +1,16 @@
<?hh // strict
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
interface RecipeWithDemo {
public function getDemoFilename(): string;
public function getDemoResult(): string;
public function getDemoXHP(): ?:xhp;
}

Some files were not shown because too many files have changed in this diff Show More