mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Merge branch 'master' into 1285-local
Conflicts: lib/linguist/language.rb lib/linguist/samples.json
This commit is contained in:
		| @@ -1,4 +1,6 @@ | |||||||
| before_install:  | before_install:  | ||||||
|  |   - git fetch origin master:master | ||||||
|  |   - git fetch origin v2.0.0:v2.0.0 | ||||||
|   - sudo apt-get install libicu-dev -y |   - sudo apt-get install libicu-dev -y | ||||||
|   - gem update --system 2.1.11 |   - gem update --system 2.1.11 | ||||||
| rvm: | rvm: | ||||||
|   | |||||||
| @@ -152,4 +152,4 @@ If you are the current maintainer of this gem: | |||||||
|    0. Test behavior locally, branch deploy, whatever needs to happen |    0. Test behavior locally, branch deploy, whatever needs to happen | ||||||
|  0. Merge github/linguist PR |  0. Merge github/linguist PR | ||||||
|  0. Tag and push: `git tag vx.xx.xx; git push --tags` |  0. Tag and push: `git tag vx.xx.xx; git push --tags` | ||||||
|  0. Push to rubygems.org -- `gem push github-linguist-2.10.12.gem` |  0. Push to rubygems.org -- `gem push github-linguist-3.0.0.gem` | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|  |  | ||||||
| require 'linguist/file_blob' | require 'linguist/file_blob' | ||||||
| require 'linguist/repository' | require 'linguist/repository' | ||||||
|  | require 'rugged' | ||||||
|  |  | ||||||
| path = ARGV[0] || Dir.pwd | path = ARGV[0] || Dir.pwd | ||||||
|  |  | ||||||
| @@ -18,7 +19,8 @@ ARGV.shift | |||||||
| breakdown = true if ARGV[0] == "--breakdown" | breakdown = true if ARGV[0] == "--breakdown" | ||||||
|  |  | ||||||
| if File.directory?(path) | if File.directory?(path) | ||||||
|   repo = Linguist::Repository.from_directory(path) |   rugged = Rugged::Repository.new(path) | ||||||
|  |   repo = Linguist::Repository.new(rugged, rugged.head.target_id) | ||||||
|   repo.languages.sort_by { |_, size| size }.reverse.each do |language, size| |   repo.languages.sort_by { |_, size| size }.reverse.each do |language, size| | ||||||
|     percentage = ((size / repo.size.to_f) * 100) |     percentage = ((size / repo.size.to_f) * 100) | ||||||
|     percentage = sprintf '%.2f' % percentage |     percentage = sprintf '%.2f' % percentage | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ Gem::Specification.new do |s| | |||||||
|   s.add_dependency 'escape_utils',    '~> 1.0.1' |   s.add_dependency 'escape_utils',    '~> 1.0.1' | ||||||
|   s.add_dependency 'mime-types',      '~> 1.19' |   s.add_dependency 'mime-types',      '~> 1.19' | ||||||
|   s.add_dependency 'pygments.rb',     '~> 0.6.0' |   s.add_dependency 'pygments.rb',     '~> 0.6.0' | ||||||
|  |   s.add_dependency 'rugged',          '~> 0.21.0' | ||||||
|  |  | ||||||
|   s.add_development_dependency 'json' |   s.add_development_dependency 'json' | ||||||
|   s.add_development_dependency 'mocha' |   s.add_development_dependency 'mocha' | ||||||
|   | |||||||
| @@ -313,15 +313,7 @@ module Linguist | |||||||
|     # |     # | ||||||
|     # Returns a Language or nil if none is detected |     # Returns a Language or nil if none is detected | ||||||
|     def language |     def language | ||||||
|       return @language if defined? @language |       @language ||= Language.detect(self) | ||||||
|  |  | ||||||
|       if defined?(@data) && @data.is_a?(String) |  | ||||||
|         data = @data |  | ||||||
|       else |  | ||||||
|         data = lambda { (binary_mime_type? || binary?) ? "" : self.data } |  | ||||||
|       end |  | ||||||
|  |  | ||||||
|       @language = Language.detect(name.to_s, data, mode) |  | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Internal: Get the lexer of the blob. |     # Internal: Get the lexer of the blob. | ||||||
|   | |||||||
| @@ -63,7 +63,8 @@ module Linguist | |||||||
|         generated_jni_header? || |         generated_jni_header? || | ||||||
|         composer_lock? || |         composer_lock? || | ||||||
|         node_modules? || |         node_modules? || | ||||||
|         vcr_cassette? |         vcr_cassette? || | ||||||
|  |         generated_by_zephir? | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Internal: Is the blob an XCode project file? |     # Internal: Is the blob an XCode project file? | ||||||
| @@ -237,6 +238,13 @@ module Linguist | |||||||
|       !!name.match(/composer.lock/) |       !!name.match(/composer.lock/) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     # Internal: Is the blob a generated by Zephir | ||||||
|  |     # | ||||||
|  |     # Returns true or false. | ||||||
|  |     def generated_by_zephir? | ||||||
|  |       !!name.match(/.\.zep\.(?:c|h|php)$/) | ||||||
|  |     end | ||||||
|  |  | ||||||
|     # Is the blob a VCR Cassette file? |     # Is the blob a VCR Cassette file? | ||||||
|     # |     # | ||||||
|     # Returns true or false |     # Returns true or false | ||||||
|   | |||||||
| @@ -92,14 +92,20 @@ module Linguist | |||||||
|  |  | ||||||
|     # Public: Detects the Language of the blob. |     # Public: Detects the Language of the blob. | ||||||
|     # |     # | ||||||
|     # name - String filename |     # blob - an object that includes the Linguist `BlobHelper` interface; | ||||||
|     # data - String blob data. A block also maybe passed in for lazy |     #       see Linguist::LazyBlob and Linguist::FileBlob for examples | ||||||
|     #        loading. This behavior is deprecated and you should always |  | ||||||
|     #        pass in a String. |  | ||||||
|     # mode - Optional String mode (defaults to nil) |  | ||||||
|     # |     # | ||||||
|     # Returns Language or nil. |     # Returns Language or nil. | ||||||
|     def self.detect(name, data, mode = nil) |     def self.detect(blob) | ||||||
|  |       name = blob.name.to_s | ||||||
|  |  | ||||||
|  |       # Check if the blob is possibly binary and bail early; this is a cheap | ||||||
|  |       # test that uses the extension name to guess a binary binary mime type. | ||||||
|  |       # | ||||||
|  |       # We'll perform a more comprehensive test later which actually involves | ||||||
|  |       # looking for binary characters in the blob | ||||||
|  |       return nil if blob.likely_binary? || blob.binary? | ||||||
|  |  | ||||||
|       # A bit of an elegant hack. If the file is executable but extensionless, |       # A bit of an elegant hack. If the file is executable but extensionless, | ||||||
|       # append a "magic" extension so it can be classified with other |       # append a "magic" extension so it can be classified with other | ||||||
|       # languages that have shebang scripts. |       # languages that have shebang scripts. | ||||||
| @@ -115,10 +121,10 @@ module Linguist | |||||||
|       # extension at all, in the case of extensionless scripts), we need to continue |       # extension at all, in the case of extensionless scripts), we need to continue | ||||||
|       # our detection work |       # our detection work | ||||||
|       if possible_languages.length > 1 |       if possible_languages.length > 1 | ||||||
|         data = data.call() if data.respond_to?(:call) |         data = blob.data | ||||||
|         possible_language_names = possible_languages.map(&:name) |         possible_language_names = possible_languages.map(&:name) | ||||||
|  |  | ||||||
|         # Don't bother with emptiness |         # Don't bother with binary contents or an empty file | ||||||
|         if data.nil? || data == "" |         if data.nil? || data == "" | ||||||
|           nil |           nil | ||||||
|         # Check if there's a shebang line and use that as authoritative |         # Check if there's a shebang line and use that as authoritative | ||||||
|   | |||||||
| @@ -89,7 +89,7 @@ Agda: | |||||||
|  |  | ||||||
| Alloy: | Alloy: | ||||||
|   type: programming  # 'modeling' would be more appropiate |   type: programming  # 'modeling' would be more appropiate | ||||||
|   lexer: Text only |   lexer: Alloy | ||||||
|   color: "#cc5c24" |   color: "#cc5c24" | ||||||
|   extensions: |   extensions: | ||||||
|   - .als |   - .als | ||||||
| @@ -157,7 +157,6 @@ Assembly: | |||||||
|   - nasm |   - nasm | ||||||
|   extensions: |   extensions: | ||||||
|   - .asm |   - .asm | ||||||
|   - .inc |  | ||||||
|  |  | ||||||
| Augeas: | Augeas: | ||||||
|   type: programming |   type: programming | ||||||
| @@ -222,6 +221,8 @@ BlitzBasic: | |||||||
|   - .decls |   - .decls | ||||||
|  |  | ||||||
| BlitzMax: | BlitzMax: | ||||||
|  |   type: programming | ||||||
|  |   color: "#cd6400" | ||||||
|   extensions: |   extensions: | ||||||
|   - .bmx |   - .bmx | ||||||
|  |  | ||||||
| @@ -529,15 +530,6 @@ Dart: | |||||||
|   extensions: |   extensions: | ||||||
|   - .dart |   - .dart | ||||||
|  |  | ||||||
| DCPU-16 ASM: |  | ||||||
|   type: programming |  | ||||||
|   lexer: dasm16 |  | ||||||
|   extensions: |  | ||||||
|   - .dasm16 |  | ||||||
|   - .dasm |  | ||||||
|   aliases: |  | ||||||
|   - dasm16 |  | ||||||
|  |  | ||||||
| Diff: | Diff: | ||||||
|   extensions: |   extensions: | ||||||
|   - .diff |   - .diff | ||||||
| @@ -744,12 +736,14 @@ GLSL: | |||||||
|   - .glsl |   - .glsl | ||||||
|   - .fp |   - .fp | ||||||
|   - .frag |   - .frag | ||||||
|  |   - .frg | ||||||
|   - .fshader |   - .fshader | ||||||
|   - .geom |   - .geom | ||||||
|   - .glslv |   - .glslv | ||||||
|   - .gshader |   - .gshader | ||||||
|   - .shader |   - .shader | ||||||
|   - .vert |   - .vert | ||||||
|  |   - .vrx | ||||||
|   - .vshader |   - .vshader | ||||||
|  |  | ||||||
| Genshi: | Genshi: | ||||||
| @@ -807,6 +801,12 @@ Gosu: | |||||||
|   extensions: |   extensions: | ||||||
|   - .gs |   - .gs | ||||||
|  |  | ||||||
|  | Grace: | ||||||
|  |   type: programming | ||||||
|  |   lexer: Text only | ||||||
|  |   extensions: | ||||||
|  |   - .grace | ||||||
|  |  | ||||||
| Grammatical Framework: | Grammatical Framework: | ||||||
|   type: programming |   type: programming | ||||||
|   lexer: Haskell |   lexer: Haskell | ||||||
| @@ -941,7 +941,7 @@ Hy: | |||||||
|  |  | ||||||
| IDL: | IDL: | ||||||
|   type: programming |   type: programming | ||||||
|   lexer: Text only |   lexer: IDL | ||||||
|   color: "#e3592c" |   color: "#e3592c" | ||||||
|   extensions: |   extensions: | ||||||
|   - .pro |   - .pro | ||||||
| @@ -960,7 +960,7 @@ Inno Setup: | |||||||
|  |  | ||||||
| Idris: | Idris: | ||||||
|   type: programming |   type: programming | ||||||
|   lexer: Text only |   lexer: Idris | ||||||
|   extensions: |   extensions: | ||||||
|   - .idr |   - .idr | ||||||
|   - .lidr |   - .lidr | ||||||
| @@ -1095,6 +1095,8 @@ JavaScript: | |||||||
|   - .pac |   - .pac | ||||||
|   - .sjs |   - .sjs | ||||||
|   - .ssjs |   - .ssjs | ||||||
|  |   - .xsjs | ||||||
|  |   - .xsjslib | ||||||
|   filenames: |   filenames: | ||||||
|   - Jakefile |   - Jakefile | ||||||
|   interpreters: |   interpreters: | ||||||
| @@ -1293,6 +1295,8 @@ Mathematica: | |||||||
|   type: programming |   type: programming | ||||||
|   extensions: |   extensions: | ||||||
|   - .mathematica |   - .mathematica | ||||||
|  |   - .m | ||||||
|  |   - .nb | ||||||
|   lexer: Text only |   lexer: Text only | ||||||
|  |  | ||||||
| Matlab: | Matlab: | ||||||
| @@ -1400,6 +1404,19 @@ Nimrod: | |||||||
|   - .nim |   - .nim | ||||||
|   - .nimrod |   - .nimrod | ||||||
|  |  | ||||||
|  | Nit: | ||||||
|  |   type: programming | ||||||
|  |   lexer: Text only | ||||||
|  |   color: "#0d8921" | ||||||
|  |   extensions: | ||||||
|  |   - .nit | ||||||
|  |  | ||||||
|  | Nix: | ||||||
|  |   type: programming | ||||||
|  |   lexer: Nix | ||||||
|  |   extensions: | ||||||
|  |   - .nix | ||||||
|  |  | ||||||
| Nu: | Nu: | ||||||
|   type: programming |   type: programming | ||||||
|   lexer: Scheme |   lexer: Scheme | ||||||
| @@ -1535,6 +1552,8 @@ PHP: | |||||||
|   - .phpt |   - .phpt | ||||||
|   filenames: |   filenames: | ||||||
|   - Phakefile |   - Phakefile | ||||||
|  |   interpreters: | ||||||
|  |   - php | ||||||
|  |  | ||||||
| Pan: | Pan: | ||||||
|   type: programming |   type: programming | ||||||
| @@ -1609,7 +1628,7 @@ Perl6: | |||||||
| Pike: | Pike: | ||||||
|   type: programming |   type: programming | ||||||
|   color: "#066ab2" |   color: "#066ab2" | ||||||
|   lexer: C |   lexer: Pike | ||||||
|   extensions: |   extensions: | ||||||
|   - .pike |   - .pike | ||||||
|   - .pmod |   - .pmod | ||||||
| @@ -1706,6 +1725,7 @@ Python: | |||||||
|   - .gyp |   - .gyp | ||||||
|   - .lmi |   - .lmi | ||||||
|   - .pyde |   - .pyde | ||||||
|  |   - .pyp | ||||||
|   - .pyt |   - .pyt | ||||||
|   - .pyw |   - .pyw | ||||||
|   - .wsgi |   - .wsgi | ||||||
| @@ -1731,6 +1751,12 @@ QML: | |||||||
|   extensions: |   extensions: | ||||||
|   - .qml |   - .qml | ||||||
|  |  | ||||||
|  | QMake: | ||||||
|  |   lexer: Text only | ||||||
|  |   extensions: | ||||||
|  |   - .pro | ||||||
|  |   - .pri | ||||||
|  |  | ||||||
| R: | R: | ||||||
|   type: programming |   type: programming | ||||||
|   color: "#198ce7" |   color: "#198ce7" | ||||||
| @@ -1870,13 +1896,17 @@ Ruby: | |||||||
|   interpreters: |   interpreters: | ||||||
|   - ruby |   - ruby | ||||||
|   filenames: |   filenames: | ||||||
|  |   - .pryrc | ||||||
|   - Appraisals |   - Appraisals | ||||||
|   - Berksfile |   - Berksfile | ||||||
|   - Buildfile |   - Buildfile | ||||||
|   - Gemfile |   - Gemfile | ||||||
|   - Gemfile.lock |   - Gemfile.lock | ||||||
|   - Guardfile |   - Guardfile | ||||||
|  |   - Jarfile | ||||||
|  |   - Mavenfile | ||||||
|   - Podfile |   - Podfile | ||||||
|  |   - Puppetfile | ||||||
|   - Thorfile |   - Thorfile | ||||||
|   - Vagrantfile |   - Vagrantfile | ||||||
|   - buildfile |   - buildfile | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								lib/linguist/lazy_blob.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/linguist/lazy_blob.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | require 'linguist/blob_helper' | ||||||
|  | require 'rugged' | ||||||
|  |  | ||||||
|  | module Linguist | ||||||
|  |   class LazyBlob | ||||||
|  |     include BlobHelper | ||||||
|  |  | ||||||
|  |     MAX_SIZE = 128 * 1024 | ||||||
|  |  | ||||||
|  |     attr_reader :repository | ||||||
|  |     attr_reader :oid | ||||||
|  |     attr_reader :name | ||||||
|  |     attr_reader :mode | ||||||
|  |  | ||||||
|  |     def initialize(repo, oid, name, mode = nil) | ||||||
|  |       @repository = repo | ||||||
|  |       @oid = oid | ||||||
|  |       @name = name | ||||||
|  |       @mode = mode | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def data | ||||||
|  |       load_blob! | ||||||
|  |       @data | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def size | ||||||
|  |       load_blob! | ||||||
|  |       @size | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     protected | ||||||
|  |     def load_blob! | ||||||
|  |       @data, @size = Rugged::Blob.to_buffer(repository, oid, MAX_SIZE) if @data.nil? | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @@ -1,4 +1,5 @@ | |||||||
| require 'linguist/file_blob' | require 'linguist/lazy_blob' | ||||||
|  | require 'rugged' | ||||||
|  |  | ||||||
| module Linguist | module Linguist | ||||||
|   # A Repository is an abstraction of a Grit::Repo or a basic file |   # A Repository is an abstraction of a Grit::Repo or a basic file | ||||||
| @@ -7,100 +8,146 @@ module Linguist | |||||||
|   # Its primary purpose is for gathering language statistics across |   # Its primary purpose is for gathering language statistics across | ||||||
|   # the entire project. |   # the entire project. | ||||||
|   class Repository |   class Repository | ||||||
|     # Public: Initialize a new Repository from a File directory |     attr_reader :repository | ||||||
|     # |  | ||||||
|     # base_path - A path String |     # Public: Create a new Repository based on the stats of | ||||||
|     # |     # an existing one | ||||||
|     # Returns a Repository |     def self.incremental(repo, commit_oid, old_commit_oid, old_stats) | ||||||
|     def self.from_directory(base_path) |       repo = self.new(repo, commit_oid) | ||||||
|       new Dir["#{base_path}/**/*"]. |       repo.load_existing_stats(old_commit_oid, old_stats) | ||||||
|         select { |f| File.file?(f) }. |       repo | ||||||
|         map { |path| FileBlob.new(path, base_path) } |  | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Initialize a new Repository |     # Public: Initialize a new Repository to be analyzed for language | ||||||
|  |     # data | ||||||
|     # |     # | ||||||
|     # enum - Enumerator that responds to `each` and |     # repo - a Rugged::Repository object | ||||||
|     #        yields Blob objects |     # commit_oid - the sha1 of the commit that will be analyzed; | ||||||
|  |     #              this is usually the master branch | ||||||
|     # |     # | ||||||
|     # Returns a Repository |     # Returns a Repository | ||||||
|     def initialize(enum) |     def initialize(repo, commit_oid) | ||||||
|       @enum = enum |       @repository = repo | ||||||
|       @computed_stats = false |       @commit_oid = commit_oid | ||||||
|       @language = @size = nil |  | ||||||
|       @sizes = Hash.new { 0 } |       raise TypeError, 'commit_oid must be a commit SHA1' unless commit_oid.is_a?(String) | ||||||
|       @file_breakdown = Hash.new { |h,k| h[k] = Array.new } |     end | ||||||
|  |  | ||||||
|  |     # Public: Load the results of a previous analysis on this repository | ||||||
|  |     # to speed up the new scan. | ||||||
|  |     # | ||||||
|  |     # The new analysis will be performed incrementally as to only take | ||||||
|  |     # into account the file changes since the last time the repository | ||||||
|  |     # was scanned | ||||||
|  |     # | ||||||
|  |     # old_commit_oid - the sha1 of the commit that was previously analyzed | ||||||
|  |     # old_stats - the result of the previous analysis, obtained by calling | ||||||
|  |     #             Repository#cache on the old repository | ||||||
|  |     # | ||||||
|  |     # Returns nothing | ||||||
|  |     def load_existing_stats(old_commit_oid, old_stats) | ||||||
|  |       @old_commit_oid = old_commit_oid | ||||||
|  |       @old_stats = old_stats | ||||||
|  |       nil | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Returns a breakdown of language stats. |     # Public: Returns a breakdown of language stats. | ||||||
|     # |     # | ||||||
|     # Examples |     # Examples | ||||||
|     # |     # | ||||||
|     #   # => { Language['Ruby'] => 46319, |     #   # => { 'Ruby' => 46319, | ||||||
|     #          Language['JavaScript'] => 258 } |     #          'JavaScript' => 258 } | ||||||
|     # |     # | ||||||
|     # Returns a Hash of Language keys and Integer size values. |     # Returns a Hash of language names and Integer size values. | ||||||
|     def languages |     def languages | ||||||
|       compute_stats |       @sizes ||= begin | ||||||
|       @sizes |         sizes = Hash.new { 0 } | ||||||
|  |         cache.each do |_, (language, size)| | ||||||
|  |           sizes[language] += size | ||||||
|  |         end | ||||||
|  |         sizes | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Get primary Language of repository. |     # Public: Get primary Language of repository. | ||||||
|     # |     # | ||||||
|     # Returns a Language |     # Returns a language name | ||||||
|     def language |     def language | ||||||
|       compute_stats |       @language ||= begin | ||||||
|       @language |         primary = languages.max_by { |(_, size)| size } | ||||||
|  |         primary && primary[0] | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Get the total size of the repository. |     # Public: Get the total size of the repository. | ||||||
|     # |     # | ||||||
|     # Returns a byte size Integer |     # Returns a byte size Integer | ||||||
|     def size |     def size | ||||||
|       compute_stats |       @size ||= languages.inject(0) { |s,(_,v)| s + v } | ||||||
|       @size |  | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Return the language breakdown of this repository by file |     # Public: Return the language breakdown of this repository by file | ||||||
|  |     # | ||||||
|  |     # Returns a map of language names => [filenames...] | ||||||
|     def breakdown_by_file |     def breakdown_by_file | ||||||
|       compute_stats |       @file_breakdown ||= begin | ||||||
|       @file_breakdown |         breakdown = Hash.new { |h,k| h[k] = Array.new } | ||||||
|  |         cache.each do |filename, (language, _)| | ||||||
|  |           breakdown[language] << filename | ||||||
|  |         end | ||||||
|  |         breakdown | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Internal: Compute language breakdown for each blob in the Repository. |     # Public: Return the cached results of the analysis | ||||||
|     # |     # | ||||||
|     # Returns nothing |     # This is a per-file breakdown that can be passed to other instances | ||||||
|     def compute_stats |     # of Linguist::Repository to perform incremental scans | ||||||
|       return if @computed_stats |     # | ||||||
|  |     # Returns a map of filename => [language, size] | ||||||
|  |     def cache | ||||||
|  |       @cache ||= begin | ||||||
|  |         if @old_commit_oid == @commit_oid | ||||||
|  |           @old_stats | ||||||
|  |         else | ||||||
|  |           compute_stats(@old_commit_oid, @commit_oid, @old_stats) | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|       @enum.each do |blob| |     protected | ||||||
|         # Skip files that are likely binary |     def compute_stats(old_commit_oid, commit_oid, cache = nil) | ||||||
|         next if blob.likely_binary? |       file_map = cache ? cache.dup : {} | ||||||
|  |       old_tree = old_commit_oid && Rugged::Commit.lookup(repository, old_commit_oid).tree | ||||||
|  |       new_tree = Rugged::Commit.lookup(repository, commit_oid).tree | ||||||
|  |  | ||||||
|  |       diff = Rugged::Tree.diff(repository, old_tree, new_tree) | ||||||
|  |  | ||||||
|  |       diff.each_delta do |delta| | ||||||
|  |         old = delta.old_file[:path] | ||||||
|  |         new = delta.new_file[:path] | ||||||
|  |  | ||||||
|  |         file_map.delete(old) | ||||||
|  |         next if delta.binary | ||||||
|  |  | ||||||
|  |         if [:added, :modified].include? delta.status | ||||||
|  |           # Skip submodules | ||||||
|  |           mode = delta.new_file[:mode] | ||||||
|  |           next if (mode & 040000) != 0 | ||||||
|  |  | ||||||
|  |           blob = Linguist::LazyBlob.new(repository, delta.new_file[:oid], new, mode.to_s(8)) | ||||||
|  |  | ||||||
|           # Skip vendored or generated blobs |           # Skip vendored or generated blobs | ||||||
|           next if blob.vendored? || blob.generated? || blob.language.nil? |           next if blob.vendored? || blob.generated? || blob.language.nil? | ||||||
|  |  | ||||||
|           # Only include programming languages and acceptable markup languages |           # Only include programming languages and acceptable markup languages | ||||||
|           if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name) |           if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name) | ||||||
|  |             file_map[new] = [blob.language.group.name, blob.size] | ||||||
|           # Build up the per-file breakdown stats |           end | ||||||
|           @file_breakdown[blob.language.group.name] << blob.name |  | ||||||
|  |  | ||||||
|           @sizes[blob.language.group] += blob.size |  | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
|  |  | ||||||
|       # Compute total size |       file_map | ||||||
|       @size = @sizes.inject(0) { |s,(_,v)| s + v } |  | ||||||
|  |  | ||||||
|       # Get primary language |  | ||||||
|       if primary = @sizes.max_by { |(_, size)| size } |  | ||||||
|         @language = primary[0] |  | ||||||
|       end |  | ||||||
|  |  | ||||||
|       @computed_stats = true |  | ||||||
|  |  | ||||||
|       nil |  | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
							
								
								
									
										131850
									
								
								lib/linguist/samples.json
									
									
									
									
									
								
							
							
						
						
									
										131850
									
								
								lib/linguist/samples.json
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -28,7 +28,7 @@ module Linguist | |||||||
|     # |     # | ||||||
|     # Returns nothing. |     # Returns nothing. | ||||||
|     def self.each(&block) |     def self.each(&block) | ||||||
|       Dir.entries(ROOT).each do |category| |       Dir.entries(ROOT).sort!.each do |category| | ||||||
|         next if category == '.' || category == '..' |         next if category == '.' || category == '..' | ||||||
|  |  | ||||||
|         # Skip text and binary for now |         # Skip text and binary for now | ||||||
|   | |||||||
| @@ -40,9 +40,13 @@ | |||||||
| - foundation.min.css | - foundation.min.css | ||||||
| - foundation.css | - foundation.css | ||||||
|  |  | ||||||
|  | # Normalize.css | ||||||
|  | - normalize.css | ||||||
|  |  | ||||||
| # Vendored dependencies | # Vendored dependencies | ||||||
| - thirdparty/ | - thirdparty/ | ||||||
| - vendors?/ | - vendors?/ | ||||||
|  | - extern(al)?/ | ||||||
|  |  | ||||||
| # Debian packaging | # Debian packaging | ||||||
| - ^debian/ | - ^debian/ | ||||||
| @@ -124,6 +128,9 @@ | |||||||
|  |  | ||||||
| ## Obj-C ## | ## Obj-C ## | ||||||
|  |  | ||||||
|  | # Cocoapods | ||||||
|  | - ^Pods/ | ||||||
|  |  | ||||||
| # Sparkle | # Sparkle | ||||||
| - (^|/)Sparkle/ | - (^|/)Sparkle/ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,3 +1,3 @@ | |||||||
| module Linguist | module Linguist | ||||||
|   VERSION = "2.12.0" |   VERSION = "3.0.3" | ||||||
| end | end | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,503 +0,0 @@ | |||||||
|  |  | ||||||
| ; flat assembler interface for Win32 |  | ||||||
| ; Copyright (c) 1999-2014, Tomasz Grysztar. |  | ||||||
| ; All rights reserved. |  | ||||||
|  |  | ||||||
| CREATE_NEW	       = 1 |  | ||||||
| CREATE_ALWAYS	       = 2 |  | ||||||
| OPEN_EXISTING	       = 3 |  | ||||||
| OPEN_ALWAYS	       = 4 |  | ||||||
| TRUNCATE_EXISTING      = 5 |  | ||||||
|  |  | ||||||
| FILE_SHARE_READ        = 1 |  | ||||||
| FILE_SHARE_WRITE       = 2 |  | ||||||
| FILE_SHARE_DELETE      = 4 |  | ||||||
|  |  | ||||||
| GENERIC_READ	       = 80000000h |  | ||||||
| GENERIC_WRITE	       = 40000000h |  | ||||||
|  |  | ||||||
| STD_INPUT_HANDLE       = 0FFFFFFF6h |  | ||||||
| STD_OUTPUT_HANDLE      = 0FFFFFFF5h |  | ||||||
| STD_ERROR_HANDLE       = 0FFFFFFF4h |  | ||||||
|  |  | ||||||
| MEM_COMMIT	       = 1000h |  | ||||||
| MEM_RESERVE	       = 2000h |  | ||||||
| MEM_DECOMMIT	       = 4000h |  | ||||||
| MEM_RELEASE	       = 8000h |  | ||||||
| MEM_FREE	       = 10000h |  | ||||||
| MEM_PRIVATE	       = 20000h |  | ||||||
| MEM_MAPPED	       = 40000h |  | ||||||
| MEM_RESET	       = 80000h |  | ||||||
| MEM_TOP_DOWN	       = 100000h |  | ||||||
|  |  | ||||||
| PAGE_NOACCESS	       = 1 |  | ||||||
| PAGE_READONLY	       = 2 |  | ||||||
| PAGE_READWRITE	       = 4 |  | ||||||
| PAGE_WRITECOPY	       = 8 |  | ||||||
| PAGE_EXECUTE	       = 10h |  | ||||||
| PAGE_EXECUTE_READ      = 20h |  | ||||||
| PAGE_EXECUTE_READWRITE = 40h |  | ||||||
| PAGE_EXECUTE_WRITECOPY = 80h |  | ||||||
| PAGE_GUARD	       = 100h |  | ||||||
| PAGE_NOCACHE	       = 200h |  | ||||||
|  |  | ||||||
| init_memory: |  | ||||||
| 	xor	eax,eax |  | ||||||
| 	mov	[memory_start],eax |  | ||||||
| 	mov	eax,esp |  | ||||||
| 	and	eax,not 0FFFh |  | ||||||
| 	add	eax,1000h-10000h |  | ||||||
| 	mov	[stack_limit],eax |  | ||||||
| 	mov	eax,[memory_setting] |  | ||||||
| 	shl	eax,10 |  | ||||||
| 	jnz	allocate_memory |  | ||||||
| 	push	buffer |  | ||||||
| 	call	[GlobalMemoryStatus] |  | ||||||
| 	mov	eax,dword [buffer+20] |  | ||||||
| 	mov	edx,dword [buffer+12] |  | ||||||
| 	cmp	eax,0 |  | ||||||
| 	jl	large_memory |  | ||||||
| 	cmp	edx,0 |  | ||||||
| 	jl	large_memory |  | ||||||
| 	shr	eax,2 |  | ||||||
| 	add	eax,edx |  | ||||||
| 	jmp	allocate_memory |  | ||||||
|     large_memory: |  | ||||||
| 	mov	eax,80000000h |  | ||||||
|     allocate_memory: |  | ||||||
| 	mov	edx,eax |  | ||||||
| 	shr	edx,2 |  | ||||||
| 	mov	ecx,eax |  | ||||||
| 	sub	ecx,edx |  | ||||||
| 	mov	[memory_end],ecx |  | ||||||
| 	mov	[additional_memory_end],edx |  | ||||||
| 	push	PAGE_READWRITE |  | ||||||
| 	push	MEM_COMMIT |  | ||||||
| 	push	eax |  | ||||||
| 	push	0 |  | ||||||
| 	call	[VirtualAlloc] |  | ||||||
| 	or	eax,eax |  | ||||||
| 	jz	not_enough_memory |  | ||||||
| 	mov	[memory_start],eax |  | ||||||
| 	add	eax,[memory_end] |  | ||||||
| 	mov	[memory_end],eax |  | ||||||
| 	mov	[additional_memory],eax |  | ||||||
| 	add	[additional_memory_end],eax |  | ||||||
| 	ret |  | ||||||
|     not_enough_memory: |  | ||||||
| 	mov	eax,[additional_memory_end] |  | ||||||
| 	shl	eax,1 |  | ||||||
| 	cmp	eax,4000h |  | ||||||
| 	jb	out_of_memory |  | ||||||
| 	jmp	allocate_memory |  | ||||||
|  |  | ||||||
| exit_program: |  | ||||||
| 	movzx	eax,al |  | ||||||
| 	push	eax |  | ||||||
| 	mov	eax,[memory_start] |  | ||||||
| 	test	eax,eax |  | ||||||
| 	jz	do_exit |  | ||||||
| 	push	MEM_RELEASE |  | ||||||
| 	push	0 |  | ||||||
| 	push	eax |  | ||||||
| 	call	[VirtualFree] |  | ||||||
|     do_exit: |  | ||||||
| 	call	[ExitProcess] |  | ||||||
|  |  | ||||||
| get_environment_variable: |  | ||||||
| 	mov	ecx,[memory_end] |  | ||||||
| 	sub	ecx,edi |  | ||||||
| 	cmp	ecx,4000h |  | ||||||
| 	jbe	buffer_for_variable_ok |  | ||||||
| 	mov	ecx,4000h |  | ||||||
|     buffer_for_variable_ok: |  | ||||||
| 	push	ecx |  | ||||||
| 	push	edi |  | ||||||
| 	push	esi |  | ||||||
| 	call	[GetEnvironmentVariable] |  | ||||||
| 	add	edi,eax |  | ||||||
| 	cmp	edi,[memory_end] |  | ||||||
| 	jae	out_of_memory |  | ||||||
| 	ret |  | ||||||
|  |  | ||||||
| open: |  | ||||||
| 	push	0 |  | ||||||
| 	push	0 |  | ||||||
| 	push	OPEN_EXISTING |  | ||||||
| 	push	0 |  | ||||||
| 	push	FILE_SHARE_READ |  | ||||||
| 	push	GENERIC_READ |  | ||||||
| 	push	edx |  | ||||||
| 	call	[CreateFile] |  | ||||||
| 	cmp	eax,-1 |  | ||||||
| 	je	file_error |  | ||||||
| 	mov	ebx,eax |  | ||||||
| 	clc |  | ||||||
| 	ret |  | ||||||
|     file_error: |  | ||||||
| 	stc |  | ||||||
| 	ret |  | ||||||
| create: |  | ||||||
| 	push	0 |  | ||||||
| 	push	0 |  | ||||||
| 	push	CREATE_ALWAYS |  | ||||||
| 	push	0 |  | ||||||
| 	push	FILE_SHARE_READ |  | ||||||
| 	push	GENERIC_WRITE |  | ||||||
| 	push	edx |  | ||||||
| 	call	[CreateFile] |  | ||||||
| 	cmp	eax,-1 |  | ||||||
| 	je	file_error |  | ||||||
| 	mov	ebx,eax |  | ||||||
| 	clc |  | ||||||
| 	ret |  | ||||||
| write: |  | ||||||
| 	push	0 |  | ||||||
| 	push	bytes_count |  | ||||||
| 	push	ecx |  | ||||||
| 	push	edx |  | ||||||
| 	push	ebx |  | ||||||
| 	call	[WriteFile] |  | ||||||
| 	or	eax,eax |  | ||||||
| 	jz	file_error |  | ||||||
| 	clc |  | ||||||
| 	ret |  | ||||||
| read: |  | ||||||
| 	mov	ebp,ecx |  | ||||||
| 	push	0 |  | ||||||
| 	push	bytes_count |  | ||||||
| 	push	ecx |  | ||||||
| 	push	edx |  | ||||||
| 	push	ebx |  | ||||||
| 	call	[ReadFile] |  | ||||||
| 	or	eax,eax |  | ||||||
| 	jz	file_error |  | ||||||
| 	cmp	ebp,[bytes_count] |  | ||||||
| 	jne	file_error |  | ||||||
| 	clc |  | ||||||
| 	ret |  | ||||||
| close: |  | ||||||
| 	push	ebx |  | ||||||
| 	call	[CloseHandle] |  | ||||||
| 	ret |  | ||||||
| lseek: |  | ||||||
| 	movzx	eax,al |  | ||||||
| 	push	eax |  | ||||||
| 	push	0 |  | ||||||
| 	push	edx |  | ||||||
| 	push	ebx |  | ||||||
| 	call	[SetFilePointer] |  | ||||||
| 	ret |  | ||||||
|  |  | ||||||
| display_string: |  | ||||||
| 	push	[con_handle] |  | ||||||
| 	call	[GetStdHandle] |  | ||||||
| 	mov	ebp,eax |  | ||||||
| 	mov	edi,esi |  | ||||||
| 	or	ecx,-1 |  | ||||||
| 	xor	al,al |  | ||||||
| 	repne	scasb |  | ||||||
| 	neg	ecx |  | ||||||
| 	sub	ecx,2 |  | ||||||
| 	push	0 |  | ||||||
| 	push	bytes_count |  | ||||||
| 	push	ecx |  | ||||||
| 	push	esi |  | ||||||
| 	push	ebp |  | ||||||
| 	call	[WriteFile] |  | ||||||
| 	ret |  | ||||||
| display_character: |  | ||||||
| 	push	ebx |  | ||||||
| 	mov	[character],dl |  | ||||||
| 	push	[con_handle] |  | ||||||
| 	call	[GetStdHandle] |  | ||||||
| 	mov	ebx,eax |  | ||||||
| 	push	0 |  | ||||||
| 	push	bytes_count |  | ||||||
| 	push	1 |  | ||||||
| 	push	character |  | ||||||
| 	push	ebx |  | ||||||
| 	call	[WriteFile] |  | ||||||
| 	pop	ebx |  | ||||||
| 	ret |  | ||||||
| display_number: |  | ||||||
| 	push	ebx |  | ||||||
| 	mov	ecx,1000000000 |  | ||||||
| 	xor	edx,edx |  | ||||||
| 	xor	bl,bl |  | ||||||
|       display_loop: |  | ||||||
| 	div	ecx |  | ||||||
| 	push	edx |  | ||||||
| 	cmp	ecx,1 |  | ||||||
| 	je	display_digit |  | ||||||
| 	or	bl,bl |  | ||||||
| 	jnz	display_digit |  | ||||||
| 	or	al,al |  | ||||||
| 	jz	digit_ok |  | ||||||
| 	not	bl |  | ||||||
|       display_digit: |  | ||||||
| 	mov	dl,al |  | ||||||
| 	add	dl,30h |  | ||||||
| 	push	ecx |  | ||||||
| 	call	display_character |  | ||||||
| 	pop	ecx |  | ||||||
|       digit_ok: |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	xor	edx,edx |  | ||||||
| 	mov	ecx,10 |  | ||||||
| 	div	ecx |  | ||||||
| 	mov	ecx,eax |  | ||||||
| 	pop	eax |  | ||||||
| 	or	ecx,ecx |  | ||||||
| 	jnz	display_loop |  | ||||||
| 	pop	ebx |  | ||||||
| 	ret |  | ||||||
|  |  | ||||||
| display_user_messages: |  | ||||||
| 	mov	[displayed_count],0 |  | ||||||
| 	call	show_display_buffer |  | ||||||
| 	cmp	[displayed_count],1 |  | ||||||
| 	jb	line_break_ok |  | ||||||
| 	je	make_line_break |  | ||||||
| 	mov	ax,word [last_displayed] |  | ||||||
| 	cmp	ax,0A0Dh |  | ||||||
| 	je	line_break_ok |  | ||||||
| 	cmp	ax,0D0Ah |  | ||||||
| 	je	line_break_ok |  | ||||||
|       make_line_break: |  | ||||||
| 	mov	word [buffer],0A0Dh |  | ||||||
| 	push	[con_handle] |  | ||||||
| 	call	[GetStdHandle] |  | ||||||
| 	push	0 |  | ||||||
| 	push	bytes_count |  | ||||||
| 	push	2 |  | ||||||
| 	push	buffer |  | ||||||
| 	push	eax |  | ||||||
| 	call	[WriteFile] |  | ||||||
|       line_break_ok: |  | ||||||
| 	ret |  | ||||||
| display_block: |  | ||||||
| 	add	[displayed_count],ecx |  | ||||||
| 	cmp	ecx,1 |  | ||||||
| 	ja	take_last_two_characters |  | ||||||
| 	jb	block_displayed |  | ||||||
| 	mov	al,[last_displayed+1] |  | ||||||
| 	mov	ah,[esi] |  | ||||||
| 	mov	word [last_displayed],ax |  | ||||||
| 	jmp	block_ok |  | ||||||
|       take_last_two_characters: |  | ||||||
| 	mov	ax,[esi+ecx-2] |  | ||||||
| 	mov	word [last_displayed],ax |  | ||||||
|       block_ok: |  | ||||||
| 	push	ecx |  | ||||||
| 	push	[con_handle] |  | ||||||
| 	call	[GetStdHandle] |  | ||||||
| 	pop	ecx |  | ||||||
| 	push	0 |  | ||||||
| 	push	bytes_count |  | ||||||
| 	push	ecx |  | ||||||
| 	push	esi |  | ||||||
| 	push	eax |  | ||||||
| 	call	[WriteFile] |  | ||||||
|       block_displayed: |  | ||||||
| 	ret |  | ||||||
|  |  | ||||||
| fatal_error: |  | ||||||
| 	mov	[con_handle],STD_ERROR_HANDLE |  | ||||||
| 	mov	esi,error_prefix |  | ||||||
| 	call	display_string |  | ||||||
| 	pop	esi |  | ||||||
| 	call	display_string |  | ||||||
| 	mov	esi,error_suffix |  | ||||||
| 	call	display_string |  | ||||||
| 	mov	al,0FFh |  | ||||||
| 	jmp	exit_program |  | ||||||
| assembler_error: |  | ||||||
| 	mov	[con_handle],STD_ERROR_HANDLE |  | ||||||
| 	call	display_user_messages |  | ||||||
| 	push	dword 0 |  | ||||||
| 	mov	ebx,[current_line] |  | ||||||
|       get_error_lines: |  | ||||||
| 	mov	eax,[ebx] |  | ||||||
| 	cmp	byte [eax],0 |  | ||||||
| 	je	get_next_error_line |  | ||||||
| 	push	ebx |  | ||||||
| 	test	byte [ebx+7],80h |  | ||||||
| 	jz	display_error_line |  | ||||||
| 	mov	edx,ebx |  | ||||||
|       find_definition_origin: |  | ||||||
| 	mov	edx,[edx+12] |  | ||||||
| 	test	byte [edx+7],80h |  | ||||||
| 	jnz	find_definition_origin |  | ||||||
| 	push	edx |  | ||||||
|       get_next_error_line: |  | ||||||
| 	mov	ebx,[ebx+8] |  | ||||||
| 	jmp	get_error_lines |  | ||||||
|       display_error_line: |  | ||||||
| 	mov	esi,[ebx] |  | ||||||
| 	call	display_string |  | ||||||
| 	mov	esi,line_number_start |  | ||||||
| 	call	display_string |  | ||||||
| 	mov	eax,[ebx+4] |  | ||||||
| 	and	eax,7FFFFFFFh |  | ||||||
| 	call	display_number |  | ||||||
| 	mov	dl,']' |  | ||||||
| 	call	display_character |  | ||||||
| 	pop	esi |  | ||||||
| 	cmp	ebx,esi |  | ||||||
| 	je	line_number_ok |  | ||||||
| 	mov	dl,20h |  | ||||||
| 	call	display_character |  | ||||||
| 	push	esi |  | ||||||
| 	mov	esi,[esi] |  | ||||||
| 	movzx	ecx,byte [esi] |  | ||||||
| 	inc	esi |  | ||||||
| 	call	display_block |  | ||||||
| 	mov	esi,line_number_start |  | ||||||
| 	call	display_string |  | ||||||
| 	pop	esi |  | ||||||
| 	mov	eax,[esi+4] |  | ||||||
| 	and	eax,7FFFFFFFh |  | ||||||
| 	call	display_number |  | ||||||
| 	mov	dl,']' |  | ||||||
| 	call	display_character |  | ||||||
|       line_number_ok: |  | ||||||
| 	mov	esi,line_data_start |  | ||||||
| 	call	display_string |  | ||||||
| 	mov	esi,ebx |  | ||||||
| 	mov	edx,[esi] |  | ||||||
| 	call	open |  | ||||||
| 	mov	al,2 |  | ||||||
| 	xor	edx,edx |  | ||||||
| 	call	lseek |  | ||||||
| 	mov	edx,[esi+8] |  | ||||||
| 	sub	eax,edx |  | ||||||
| 	jz	line_data_displayed |  | ||||||
| 	push	eax |  | ||||||
| 	xor	al,al |  | ||||||
| 	call	lseek |  | ||||||
| 	mov	ecx,[esp] |  | ||||||
| 	mov	edx,[additional_memory] |  | ||||||
| 	lea	eax,[edx+ecx] |  | ||||||
| 	cmp	eax,[additional_memory_end] |  | ||||||
| 	ja	out_of_memory |  | ||||||
| 	call	read |  | ||||||
| 	call	close |  | ||||||
| 	pop	ecx |  | ||||||
| 	mov	esi,[additional_memory] |  | ||||||
|       get_line_data: |  | ||||||
| 	mov	al,[esi] |  | ||||||
| 	cmp	al,0Ah |  | ||||||
| 	je	display_line_data |  | ||||||
| 	cmp	al,0Dh |  | ||||||
| 	je	display_line_data |  | ||||||
| 	cmp	al,1Ah |  | ||||||
| 	je	display_line_data |  | ||||||
| 	or	al,al |  | ||||||
| 	jz	display_line_data |  | ||||||
| 	inc	esi |  | ||||||
| 	loop	get_line_data |  | ||||||
|       display_line_data: |  | ||||||
| 	mov	ecx,esi |  | ||||||
| 	mov	esi,[additional_memory] |  | ||||||
| 	sub	ecx,esi |  | ||||||
| 	call	display_block |  | ||||||
|       line_data_displayed: |  | ||||||
| 	mov	esi,cr_lf |  | ||||||
| 	call	display_string |  | ||||||
| 	pop	ebx |  | ||||||
| 	or	ebx,ebx |  | ||||||
| 	jnz	display_error_line |  | ||||||
| 	mov	esi,error_prefix |  | ||||||
| 	call	display_string |  | ||||||
| 	pop	esi |  | ||||||
| 	call	display_string |  | ||||||
| 	mov	esi,error_suffix |  | ||||||
| 	call	display_string |  | ||||||
| 	mov	al,2 |  | ||||||
| 	jmp	exit_program |  | ||||||
|  |  | ||||||
| make_timestamp: |  | ||||||
| 	push	buffer |  | ||||||
| 	call	[GetSystemTime] |  | ||||||
| 	movzx	ecx,word [buffer] |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	sub	eax,1970 |  | ||||||
| 	mov	ebx,365 |  | ||||||
| 	mul	ebx |  | ||||||
| 	mov	ebp,eax |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	sub	eax,1969 |  | ||||||
| 	shr	eax,2 |  | ||||||
| 	add	ebp,eax |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	sub	eax,1901 |  | ||||||
| 	mov	ebx,100 |  | ||||||
| 	div	ebx |  | ||||||
| 	sub	ebp,eax |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	xor	edx,edx |  | ||||||
| 	sub	eax,1601 |  | ||||||
| 	mov	ebx,400 |  | ||||||
| 	div	ebx |  | ||||||
| 	add	ebp,eax |  | ||||||
| 	movzx	ecx,word [buffer+2] |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	dec	eax |  | ||||||
| 	mov	ebx,30 |  | ||||||
| 	mul	ebx |  | ||||||
| 	add	ebp,eax |  | ||||||
| 	cmp	ecx,8 |  | ||||||
| 	jbe	months_correction |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	sub	eax,7 |  | ||||||
| 	shr	eax,1 |  | ||||||
| 	add	ebp,eax |  | ||||||
| 	mov	ecx,8 |  | ||||||
|       months_correction: |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	shr	eax,1 |  | ||||||
| 	add	ebp,eax |  | ||||||
| 	cmp	ecx,2 |  | ||||||
| 	jbe	day_correction_ok |  | ||||||
| 	sub	ebp,2 |  | ||||||
| 	movzx	ecx,word [buffer] |  | ||||||
| 	test	ecx,11b |  | ||||||
| 	jnz	day_correction_ok |  | ||||||
| 	xor	edx,edx |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	mov	ebx,100 |  | ||||||
| 	div	ebx |  | ||||||
| 	or	edx,edx |  | ||||||
| 	jnz	day_correction |  | ||||||
| 	mov	eax,ecx |  | ||||||
| 	mov	ebx,400 |  | ||||||
| 	div	ebx |  | ||||||
| 	or	edx,edx |  | ||||||
| 	jnz	day_correction_ok |  | ||||||
|       day_correction: |  | ||||||
| 	inc	ebp |  | ||||||
|       day_correction_ok: |  | ||||||
| 	movzx	eax,word [buffer+6] |  | ||||||
| 	dec	eax |  | ||||||
| 	add	eax,ebp |  | ||||||
| 	mov	ebx,24 |  | ||||||
| 	mul	ebx |  | ||||||
| 	movzx	ecx,word [buffer+8] |  | ||||||
| 	add	eax,ecx |  | ||||||
| 	mov	ebx,60 |  | ||||||
| 	mul	ebx |  | ||||||
| 	movzx	ecx,word [buffer+10] |  | ||||||
| 	add	eax,ecx |  | ||||||
| 	mov	ebx,60 |  | ||||||
| 	mul	ebx |  | ||||||
| 	movzx	ecx,word [buffer+12] |  | ||||||
| 	add	eax,ecx |  | ||||||
| 	adc	edx,0 |  | ||||||
| 	ret |  | ||||||
|  |  | ||||||
| error_prefix db 'error: ',0 |  | ||||||
| error_suffix db '.' |  | ||||||
| cr_lf db 0Dh,0Ah,0 |  | ||||||
| line_number_start db ' [',0 |  | ||||||
| line_data_start db ':',0Dh,0Ah,0 |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										25
									
								
								samples/BlitzMax/sample.bmx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								samples/BlitzMax/sample.bmx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | SuperStrict | ||||||
|  |  | ||||||
|  | Framework Brl.StandardIO | ||||||
|  |  | ||||||
|  | Type TMyType | ||||||
|  | 	Field property:int | ||||||
|  |  | ||||||
|  | 	Function A:int(param:int) | ||||||
|  | 		'do nothing | ||||||
|  | 	End Function | ||||||
|  |  | ||||||
|  | 	Method B:int(param:int) | ||||||
|  | 		'do nothing | ||||||
|  | 	End Method | ||||||
|  | End Type | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Global my:TMyType = new TMyType | ||||||
|  | ?Win32 | ||||||
|  | 	my.A() | ||||||
|  | 	my.B() | ||||||
|  | ?Linux | ||||||
|  | 	my.B() | ||||||
|  | 	my.A() | ||||||
|  | ? | ||||||
							
								
								
									
										6
									
								
								samples/GLSL/myfragment.frg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								samples/GLSL/myfragment.frg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | varying vec4 v_color; | ||||||
|  |  | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  | 	gl_FragColor = v_color; | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								samples/GLSL/myvertex.vrx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								samples/GLSL/myvertex.vrx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | uniform mat4 u_MVPMatrix; | ||||||
|  |  | ||||||
|  | attribute vec4 a_position; | ||||||
|  | attribute vec4 a_color; | ||||||
|  |  | ||||||
|  | varying vec4 v_color; | ||||||
|  |  | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  | 	v_color = a_color; | ||||||
|  | 	gl_Position =  u_MVPMatrix * pos; | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								samples/Grace/ackerman_function.grace
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								samples/Grace/ackerman_function.grace
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | method ack (m : Number, n : Number) -> Number { | ||||||
|  |   print "ack {m} {n}" | ||||||
|  |   if (m < = 0) then {n + 1} | ||||||
|  |    elseif {n <= 0} then {ack((m -1), 1)} | ||||||
|  |    else {ack(m -1, ack(m, n-1))} | ||||||
|  | } | ||||||
							
								
								
									
										554
									
								
								samples/Grace/grace_IDE.grace
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										554
									
								
								samples/Grace/grace_IDE.grace
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,554 @@ | |||||||
|  | import "gtk" as gtk | ||||||
|  | import "io" as io | ||||||
|  | import "mgcollections" as collections | ||||||
|  | import "button_factory" as button_factory | ||||||
|  | import "dialog_factory" as dialog_factory | ||||||
|  | import "syntax_highlighter" as highlighter | ||||||
|  | import "auto_completer" as aComp | ||||||
|  |  | ||||||
|  | //TODO | ||||||
|  |  | ||||||
|  | // Autocomplete typing | ||||||
|  |  | ||||||
|  | // FileChooser | ||||||
|  | // Themes | ||||||
|  |  | ||||||
|  | // Details for the Top Level Window | ||||||
|  | def window = gtk.window(gtk.GTK_WINDOW_TOPLEVEL) | ||||||
|  | window.title := "Grace" | ||||||
|  | window.set_default_size(700, 700) | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Placeholder for the console window that can be popped out | ||||||
|  | // of the main window | ||||||
|  | var popped := gtk.window(gtk.GTK_WINDOW_TOPLEVEL) | ||||||
|  |  | ||||||
|  | // Initialise the Boxes | ||||||
|  | def mBox = gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2) | ||||||
|  | def buttonBox = gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 2) | ||||||
|  | var consoleButtons := gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 3) | ||||||
|  | var consoleBox := gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2) | ||||||
|  | var editorBox := gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2) | ||||||
|  | var splitPane := gtk.paned(gtk.GTK_ORIENTATION_VERTICAL, 2) | ||||||
|  | def menuBox = gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 4) | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Initialise the buttons | ||||||
|  | def runButton = button_factory.make("run") | ||||||
|  | var clearButton := button_factory.make("clear") | ||||||
|  | var outButton := button_factory.make("out") | ||||||
|  | var errorButton := button_factory.make("error") | ||||||
|  | var popButton := button_factory.make("pop") | ||||||
|  | def newButton = button_factory.make("new") | ||||||
|  | def openButton = button_factory.make("open") | ||||||
|  | def saveButton = button_factory.make("save") | ||||||
|  | def saveAsButton = button_factory.make("saveAs") | ||||||
|  | def closeButton = button_factory.make("close") | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Details for the default text editor and scrolled window | ||||||
|  | var tEdit := gtk.text_view | ||||||
|  | tEdit.set_size_request(700, 400) | ||||||
|  |  | ||||||
|  | var scrolled_main := gtk.scrolled_window | ||||||
|  | scrolled_main.set_size_request(700, 400) | ||||||
|  | scrolled_main.add(tEdit) | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Widget that allows multiple files to be edited (tabs) | ||||||
|  | var notebook := gtk.notebook | ||||||
|  | notebook.scrollable := true | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Maps for holding the text_views and scrolled_windows | ||||||
|  | var editor_map := collections.map.new | ||||||
|  | editor_map.put(0, tEdit) | ||||||
|  | var scrolled_map := collections.map.new | ||||||
|  | scrolled_map.put(0, scrolled_main) | ||||||
|  |  | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Class that manages the syntax highlighting (This needs to be passed around otherwise | ||||||
|  | // the text_tag table gets confused, ie there can only be one) | ||||||
|  | def lighter = highlighter.Syntax_Highlighter.new(notebook, editor_map) | ||||||
|  | tEdit.buffer.on "changed" do { | ||||||
|  |     lighter.highlightLine | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Class that manages any auto completion that is required | ||||||
|  | def completer =  aComp.Auto_Completer.new(window, notebook, editor_map) | ||||||
|  |  | ||||||
|  | // Utility methods | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | method deleteCompileFiles(page_num : Number) { | ||||||
|  |     def cur_scrolled = scrolled_map.get(page_num) | ||||||
|  |     var filename := notebook.get_tab_label_text(cur_scrolled) | ||||||
|  |     filename := filename.substringFrom(0)to(filename.size - 7) //Removes .grace extension | ||||||
|  |  | ||||||
|  |     io.system("rm -f files/" ++ filename) | ||||||
|  |     io.system("rm -f files/" ++ filename ++ ".c") | ||||||
|  |     io.system("rm -f files/" ++ filename ++ ".gcn") | ||||||
|  |     io.system("rm -f files/" ++ filename ++ ".gct") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | var currentConsole := "output"      // Which console is being shown | ||||||
|  | var out := false | ||||||
|  |  | ||||||
|  |  | ||||||
|  | var outText := "" | ||||||
|  | var errorText := "" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Give actions to the buttons | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | runButton.on "clicked" do { | ||||||
|  |     clearConsoles() | ||||||
|  |  | ||||||
|  |     // Get the details for the current page selected | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page_label = notebook.get_tab_label_text(cur_scrolled) | ||||||
|  |  | ||||||
|  |     // Initialise text iterators | ||||||
|  |     def sIter = gtk.text_iter | ||||||
|  |     def eIter = gtk.text_iter | ||||||
|  |  | ||||||
|  |     // Set one at the beggining and one at the end of the text | ||||||
|  |     cur_page.buffer.get_iter_at_offset(sIter, 0) | ||||||
|  |     cur_page.buffer.get_iter_at_offset(eIter, -1) | ||||||
|  |  | ||||||
|  |     // Get the text between the text iterators | ||||||
|  |     def text = cur_page.buffer.get_text(sIter, eIter, true) | ||||||
|  |  | ||||||
|  |     // Save the text to the file (in case the user hasn't already saved it) | ||||||
|  |     def file = io.open("files/" ++ cur_page_label, "w") | ||||||
|  |     file.write(text) | ||||||
|  |     file.close | ||||||
|  |  | ||||||
|  |     // Run the program and pipe the output and errors into files to be read | ||||||
|  |     io.system("../minigrace/minigrace " ++ "files/" ++ cur_page_label ++ " > output.txt 2> error.txt") | ||||||
|  |     def outputFile = io.open("output.txt", "r") | ||||||
|  |     def errorFile = io.open("error.txt", "r") | ||||||
|  |     outText := outputFile.read | ||||||
|  |     errorText := errorFile.read | ||||||
|  |  | ||||||
|  |     io.system("rm -f output.txt error.txt") | ||||||
|  |  | ||||||
|  |     var switched := false | ||||||
|  |  | ||||||
|  |     // Change the console to output if there is output text | ||||||
|  |     if((outText.size > 0) && (currentConsole != "output")) then { | ||||||
|  |         switch_to_output() | ||||||
|  |         switched := true | ||||||
|  |     } | ||||||
|  |     // Change the console to errors if there were errors | ||||||
|  |     if((errorText.size > 0) && (currentConsole != "errors")) then { | ||||||
|  |         switch_to_errors() | ||||||
|  |         switched := true | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Remember to populate the console if it wasn't switched | ||||||
|  |     if(!switched) then { | ||||||
|  |         populateConsoles | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | clearButton.on "clicked" do { | ||||||
|  |     clearConsoles() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | outButton.on "clicked" do { | ||||||
|  |     switch_to_output() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | errorButton.on "clicked" do { | ||||||
|  |     switch_to_errors() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | popButton.on "clicked" do { | ||||||
|  |     if(out) then { | ||||||
|  |         popIn() | ||||||
|  |     } else { | ||||||
|  |         popOut() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Gives a dialog to let the user create a new file to edit | ||||||
|  | newButton.on "clicked" do { | ||||||
|  |     def new_window_class = dialog_factory.new.new(notebook, editor_map, scrolled_map, lighter) | ||||||
|  |  | ||||||
|  |     def new_window = new_window_class.window() | ||||||
|  |     new_window.show_all | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Gives a dialog that lets the user open a file to edit | ||||||
|  | openButton.on "clicked" do { | ||||||
|  |     def open_window_class = dialog_factory.open.new(notebook, editor_map, scrolled_map, lighter) | ||||||
|  |  | ||||||
|  |     def open_window = open_window_class.window() | ||||||
|  |     open_window.show_all | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Saves the current file (if the name is Untitled.grace it will ask for a new name) | ||||||
|  | saveButton.on "clicked" do { | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page_label = notebook.get_tab_label_text(cur_scrolled) | ||||||
|  |  | ||||||
|  |     if(cur_page_label == "Untitled.grace") then { | ||||||
|  |         def saveAs_window_class = dialog_factory.save.new(notebook, editor_map, scrolled_map, true) | ||||||
|  |  | ||||||
|  |         def saveAs_window = saveAs_window_class.window() | ||||||
|  |         saveAs_window.show_all | ||||||
|  |     } else { | ||||||
|  |         // Initialise text iterators | ||||||
|  |         def sIter = gtk.text_iter | ||||||
|  |         def eIter = gtk.text_iter | ||||||
|  |  | ||||||
|  |         // Set one at the beggining and one at the end of the text | ||||||
|  |         cur_page.buffer.get_iter_at_offset(sIter, 0) | ||||||
|  |         cur_page.buffer.get_iter_at_offset(eIter, -1) | ||||||
|  |  | ||||||
|  |         // Get the text between the text iterators | ||||||
|  |         def text = cur_page.buffer.get_text(sIter, eIter, true) | ||||||
|  |  | ||||||
|  |         // Save the file | ||||||
|  |         def file = io.open("files/" ++ cur_page_label, "w") | ||||||
|  |         file.write(text) | ||||||
|  |         file.close | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Gives a dialog that lets the user save the file with a new name | ||||||
|  | saveAsButton.on "clicked" do { | ||||||
|  |     def saveAs_window_class = dialog_factory.save.new(notebook, editor_map, scrolled_map, false) | ||||||
|  |  | ||||||
|  |     def saveAs_window = saveAs_window_class.window() | ||||||
|  |     saveAs_window.show_all | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // This will close a tab on the notebook | ||||||
|  | // It also "removes" the page from the map, | ||||||
|  | // by creating a new temporary map and putting all but | ||||||
|  | // the removed page in. | ||||||
|  | closeButton.on "clicked" do { | ||||||
|  |     def page_num = notebook.current_page | ||||||
|  |     def num_pages = notebook.n_pages | ||||||
|  |  | ||||||
|  |     if(num_pages > 1) then { | ||||||
|  |         deleteCompileFiles(page_num) | ||||||
|  |  | ||||||
|  |         def e_map = collections.map.new | ||||||
|  |         def s_map = collections.map.new | ||||||
|  |  | ||||||
|  |         // Copy every page up to the current page into the new maps | ||||||
|  |         var x := 0 | ||||||
|  |         while {x < page_num} do { | ||||||
|  |             var eValue := editor_map.get(x) | ||||||
|  |             var sValue := scrolled_map.get(x) | ||||||
|  |             e_map.put(x, eValue) | ||||||
|  |             s_map.put(x, sValue) | ||||||
|  |  | ||||||
|  |             x := x + 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Copy every page after the current page into the new map (shifted one down) | ||||||
|  |         x := page_num + 1 | ||||||
|  |         while {x < num_pages} do { | ||||||
|  |             var eValue := editor_map.get(x) | ||||||
|  |             var sValue := scrolled_map.get(x) | ||||||
|  |             e_map.put((x - 1), eValue) | ||||||
|  |             s_map.put((x - 1), sValue) | ||||||
|  |  | ||||||
|  |             x := x + 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         editor_map := e_map | ||||||
|  |         scrolled_map := s_map | ||||||
|  |         notebook.remove_page(page_num) | ||||||
|  |  | ||||||
|  |         notebook.show_all | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Consoles: | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | var outConsole := gtk.text_view | ||||||
|  | var outScroll := gtk.scrolled_window | ||||||
|  | var errorConsole := gtk.text_view | ||||||
|  | var errorScroll := gtk.scrolled_window | ||||||
|  | var errorTag := errorConsole.buffer.create_tag("fixed", "foreground", "red") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Creates a new output console | ||||||
|  | method createOut { | ||||||
|  |     outConsole := gtk.text_view | ||||||
|  |     outScroll := gtk.scrolled_window | ||||||
|  |     outScroll.add(outConsole) | ||||||
|  |     if(out) then { | ||||||
|  |         outConsole.set_size_request(400, 400) | ||||||
|  |         outScroll.set_size_request(400, 400) | ||||||
|  |     } else { | ||||||
|  |         outConsole.set_size_request(700, 200) | ||||||
|  |         outScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |     outConsole.editable := false | ||||||
|  |     outConsole.buffer.set_text("[Output]:", -1) | ||||||
|  | } | ||||||
|  | createOut() | ||||||
|  |  | ||||||
|  | // Creates a new error console | ||||||
|  | method createError { | ||||||
|  |     errorConsole := gtk.text_view | ||||||
|  |     errorScroll := gtk.scrolled_window | ||||||
|  |     errorScroll.add(errorConsole) | ||||||
|  |     if(out) then { | ||||||
|  |         errorConsole.set_size_request(400, 400) | ||||||
|  |         errorScroll.set_size_request(400, 400) | ||||||
|  |     } else { | ||||||
|  |         errorConsole.set_size_request(700, 200) | ||||||
|  |         errorScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |     errorConsole.editable := false | ||||||
|  |     errorConsole.buffer.set_text("[Errors]:", -1) | ||||||
|  |     errorTag := errorConsole.buffer.create_tag("fixed", "foreground", "red") | ||||||
|  | } | ||||||
|  | createError() | ||||||
|  |  | ||||||
|  | // Switches the console being shown to be output. This requires | ||||||
|  | // the output console to be remade as it would have been destroyed when | ||||||
|  | // it was switched previously | ||||||
|  | method switch_to_output { | ||||||
|  |     if(currentConsole != "output") then { | ||||||
|  |         currentConsole := "output" | ||||||
|  |         consoleBox.remove(errorScroll)     // This destroys the errorConsole | ||||||
|  |  | ||||||
|  |         createOut() | ||||||
|  |  | ||||||
|  |         consoleBox.add(outScroll) | ||||||
|  |  | ||||||
|  |         populateConsoles() | ||||||
|  |         if(out) then { | ||||||
|  |             popped.show_all | ||||||
|  |         } else { | ||||||
|  |             window.show_all | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Switches the console being shown to be errors. This requires | ||||||
|  | // the error console to be remade as it would have been destroyed when | ||||||
|  | // it was switched previously | ||||||
|  | method switch_to_errors { | ||||||
|  |     if(currentConsole != "errors") then { | ||||||
|  |         currentConsole := "errors" | ||||||
|  |         consoleBox.remove(outScroll)       // This destroys the outConsole | ||||||
|  |  | ||||||
|  |         createError() | ||||||
|  |  | ||||||
|  |         consoleBox.add(errorScroll) | ||||||
|  |  | ||||||
|  |         populateConsoles() | ||||||
|  |         if(out) then { | ||||||
|  |             popped.show_all | ||||||
|  |         } else { | ||||||
|  |             window.show_all | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // If there is text to be put into the consoles this will add it | ||||||
|  | method populateConsoles { | ||||||
|  |     if((outText.size > 0) && (currentConsole == "output")) then { | ||||||
|  |         outConsole.buffer.set_text(outText, -1) | ||||||
|  |     } | ||||||
|  |     if((errorText.size > 0) && (currentConsole == "errors")) then { | ||||||
|  |         def sIter = gtk.text_iter | ||||||
|  |         def eIter = gtk.text_iter | ||||||
|  |  | ||||||
|  |         errorConsole.buffer.set_text(errorText, -1) | ||||||
|  |         errorConsole.buffer.get_iter_at_offset(sIter, 0) | ||||||
|  |         errorConsole.buffer.get_iter_at_offset(eIter, -1) | ||||||
|  |         errorConsole.buffer.apply_tag(errorTag, sIter, eIter) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | method clearConsoles { | ||||||
|  |     if(currentConsole == "output") then { | ||||||
|  |         outConsole.buffer.set_text("[Output]:", -1) | ||||||
|  |         outText := "" | ||||||
|  |     } | ||||||
|  |     if(currentConsole == "errors") then { | ||||||
|  |         errorConsole.buffer.set_text("[Errors]:", -1) | ||||||
|  |         errorText := "" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Identical as the popIn method, but can be connected to the window's destroy button | ||||||
|  | def popInBlock = { | ||||||
|  |     consoleBox.reparent(splitPane) | ||||||
|  |     popButton.label := "Pop Out" | ||||||
|  |  | ||||||
|  |     if(currentConsole == "output") then { | ||||||
|  |         outConsole.set_size_request(700, 200) | ||||||
|  |         outScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |     if(currentConsole == "errors") then { | ||||||
|  |      errorConsole.set_size_request(700, 200) | ||||||
|  |      errorScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |  | ||||||
|  |     cur_page.set_size_request(700, 400) | ||||||
|  |     cur_scrolled.set_size_request(700, 400) | ||||||
|  |  | ||||||
|  |     out := false | ||||||
|  |     popped.visible := false | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // This pops the console out into a separate window | ||||||
|  | method popOut { | ||||||
|  |     popped := gtk.window(gtk.GTK_WINDOW_TOPLEVEL) | ||||||
|  |  | ||||||
|  |     consoleBox.reparent(popped) | ||||||
|  |     popButton.label := "Pop In" | ||||||
|  |  | ||||||
|  |     if(currentConsole == "output") then { | ||||||
|  |         outConsole.set_size_request(400, 400) | ||||||
|  |         outScroll.set_size_request(400, 400) | ||||||
|  |     } | ||||||
|  |     if(currentConsole == "errors") then { | ||||||
|  |         errorConsole.set_size_request(400, 400) | ||||||
|  |         errorScroll.set_size_request(400, 400) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |  | ||||||
|  |     cur_page.set_size_request(700, 580) | ||||||
|  |     cur_scrolled.set_size_request(700, 580) | ||||||
|  |  | ||||||
|  |     out := true | ||||||
|  |     popped.visible := true | ||||||
|  |     popped.connect("destroy", popInBlock) | ||||||
|  |     popped.show_all | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Puts the console back into the main window | ||||||
|  | method popIn { | ||||||
|  |     consoleBox.reparent(splitPane) | ||||||
|  |     popButton.label := "Pop Out" | ||||||
|  |  | ||||||
|  |     if(currentConsole == "output") then { | ||||||
|  |         outConsole.set_size_request(700, 200) | ||||||
|  |         outScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |     if(currentConsole == "errors") then { | ||||||
|  |         errorConsole.set_size_request(700, 200) | ||||||
|  |         errorScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |  | ||||||
|  |     cur_page.set_size_request(700, 400) | ||||||
|  |     cur_scrolled.set_size_request(700, 400) | ||||||
|  |  | ||||||
|  |     out := false | ||||||
|  |     popped.visible := false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | clearConsoles() | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Patch everything together | ||||||
|  |  | ||||||
|  | var hSeparator1 := gtk.separator(gtk.GTK_ORIENTATION_HORIZONTAL) | ||||||
|  | var hSeparator2 := gtk.separator(gtk.GTK_ORIENTATION_HORIZONTAL) | ||||||
|  |  | ||||||
|  | menuBox.add(newButton) | ||||||
|  | menuBox.add(openButton) | ||||||
|  | menuBox.add(saveButton) | ||||||
|  | menuBox.add(saveAsButton) | ||||||
|  | buttonBox.add(runButton) | ||||||
|  | buttonBox.add(closeButton) | ||||||
|  |  | ||||||
|  | consoleButtons.add(outButton) | ||||||
|  | consoleButtons.add(errorButton) | ||||||
|  | consoleButtons.add(clearButton) | ||||||
|  | consoleButtons.add(popButton) | ||||||
|  |  | ||||||
|  | consoleBox.add(hSeparator1) | ||||||
|  | consoleBox.add(consoleButtons) | ||||||
|  | consoleBox.add(outScroll) | ||||||
|  |  | ||||||
|  | editorBox.add(hSeparator2) | ||||||
|  | notebook.add(scrolled_main) | ||||||
|  | notebook.set_tab_label_text(scrolled_main, "Untitled.grace") | ||||||
|  | editorBox.add(notebook) | ||||||
|  |  | ||||||
|  | splitPane.add1(editorBox) | ||||||
|  | splitPane.add2(consoleBox) | ||||||
|  |  | ||||||
|  | mBox.add(menuBox) | ||||||
|  | mBox.add(buttonBox) | ||||||
|  | mBox.add(splitPane) | ||||||
|  |  | ||||||
|  | window.add(mBox) | ||||||
|  |  | ||||||
|  | def exit = { | ||||||
|  |     var x := 0 | ||||||
|  |     while {x < notebook.n_pages} do { | ||||||
|  |         deleteCompileFiles(x) | ||||||
|  |  | ||||||
|  |         x := x + 1 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Delete the compile files of the IDE | ||||||
|  |     io.system("rm -f Grace_IDE.gct Grace_IDE.c Grace_IDE.gcn") | ||||||
|  |     io.system("rm -f scanner.gct scanner.c scanner.gcn") | ||||||
|  |     io.system("rm -f syntax_highlighter.gct syntax_highlighter.c syntax_highlighter.gcn") | ||||||
|  |     io.system("rm -f syntax_colors.gct syntax_colors.c syntax_colors.gcn") | ||||||
|  |     io.system("rm -f button_factory.gct button_factory.c button_factory.gcn") | ||||||
|  |     io.system("rm -f dialog_factory.gct dialog_factory.c dialog_factory.gcn") | ||||||
|  |     io.system("rm -f auto_completer.gct auto_completer.c auto_completer.gcn") | ||||||
|  |  | ||||||
|  |     print "Grace IDE Closed Successfully" | ||||||
|  |     gtk.main_quit | ||||||
|  | } | ||||||
|  |  | ||||||
|  | window.connect("destroy", exit) | ||||||
|  | window.show_all | ||||||
|  |  | ||||||
|  | gtk.main | ||||||
							
								
								
									
										24
									
								
								samples/JavaScript/helloHanaEndpoint.xsjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								samples/JavaScript/helloHanaEndpoint.xsjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | /* | ||||||
|  |  invoke endpoint by calling in a browser: | ||||||
|  |  http://<hanaserveradress>:<xsengineport(usually 8000)>/<path>/<to>/<endpoint>/helloHanaMath.xsjslib?x=4&y=2 | ||||||
|  |  e.g.: | ||||||
|  |  http://192.168.178.20:8000/geekflyer/linguist/helloHanaEndpoint.xsjs?x=4&y=2 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | var hanaMath = $.import("./helloHanaMath.xsjslib"); | ||||||
|  |  | ||||||
|  | var x = parseFloat($.request.parameters.get("x")); | ||||||
|  | var y = parseFloat($.request.parameters.get("y")); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | var result = hanaMath.multiply(x, y); | ||||||
|  |  | ||||||
|  | var output = { | ||||||
|  |     title: "Hello HANA XS - do some simple math", | ||||||
|  |     input: {x: x, y: y}, | ||||||
|  |     result: result | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | $.response.contentType = "application/json"; | ||||||
|  | $.response.statusCode = $.net.http.OK; | ||||||
|  | $.response.setBody(JSON.stringify(output)); | ||||||
							
								
								
									
										9
									
								
								samples/JavaScript/helloHanaMath.xsjslib
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								samples/JavaScript/helloHanaMath.xsjslib
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | /* simple hana xs demo library, which can be used by multiple endpoints */ | ||||||
|  |  | ||||||
|  | function multiply(x, y) { | ||||||
|  |     return x * y; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function add(x, y) { | ||||||
|  |     return x + y; | ||||||
|  | } | ||||||
							
								
								
									
										232
									
								
								samples/Mathematica/MiscCalculations.nb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								samples/Mathematica/MiscCalculations.nb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,232 @@ | |||||||
|  | (* Content-type: application/vnd.wolfram.mathematica *) | ||||||
|  |  | ||||||
|  | (*** Wolfram Notebook File ***) | ||||||
|  | (* http://www.wolfram.com/nb *) | ||||||
|  |  | ||||||
|  | (* CreatedBy='Mathematica 9.0' *) | ||||||
|  |  | ||||||
|  | (*CacheID: 234*) | ||||||
|  | (* Internal cache information: | ||||||
|  | NotebookFileLineBreakTest | ||||||
|  | NotebookFileLineBreakTest | ||||||
|  | NotebookDataPosition[       157,          7] | ||||||
|  | NotebookDataLength[      7164,        223] | ||||||
|  | NotebookOptionsPosition[      6163,        182] | ||||||
|  | NotebookOutlinePosition[      6508,        197] | ||||||
|  | CellTagsIndexPosition[      6465,        194] | ||||||
|  | WindowFrame->Normal*) | ||||||
|  |  | ||||||
|  | (* Beginning of Notebook Content *) | ||||||
|  | Notebook[{ | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{ | ||||||
|  |   RowBox[{"Solve", "[",  | ||||||
|  |    RowBox[{ | ||||||
|  |     RowBox[{"y", "'"}], "\[Equal]", " ", "xy"}], "]"}],  | ||||||
|  |   "\[IndentingNewLine]"}]], "Input", | ||||||
|  |  CellChangeTimes->{{3.6112716342092056`*^9, 3.6112716549793935`*^9}}], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"{",  | ||||||
|  |   RowBox[{"{",  | ||||||
|  |    RowBox[{"xy", "\[Rule]",  | ||||||
|  |     SuperscriptBox["y", "\[Prime]", | ||||||
|  |      MultilineFunction->None]}], "}"}], "}"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.6112716579295626`*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"Log", "[",  | ||||||
|  |   RowBox[{"Sin", "[", "38", "]"}], "]"}]], "Input", | ||||||
|  |  CellChangeTimes->{{3.611271663920905*^9, 3.6112716759275913`*^9}}], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"Log", "[",  | ||||||
|  |   RowBox[{"Sin", "[", "38", "]"}], "]"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.611271678256725*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"N", "[",  | ||||||
|  |   RowBox[{"Log", "[",  | ||||||
|  |    RowBox[{"Sin", "[", "38", "]"}], "]"}], "]"}]], "Input", | ||||||
|  |  NumberMarks->False], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"-", "1.2161514009320473`"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.611271682061942*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"Abs", "[",  | ||||||
|  |   RowBox[{"-", "1.2161514009320473`"}], "]"}]], "Input", | ||||||
|  |  NumberMarks->False], | ||||||
|  |  | ||||||
|  | Cell[BoxData["1.2161514009320473`"], "Output", | ||||||
|  |  CellChangeTimes->{3.6112716842780695`*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"RealDigits", "[", "1.2161514009320473`", "]"}]], "Input", | ||||||
|  |  NumberMarks->False], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"{",  | ||||||
|  |   RowBox[{ | ||||||
|  |    RowBox[{"{",  | ||||||
|  |     RowBox[{ | ||||||
|  |     "1", ",", "2", ",", "1", ",", "6", ",", "1", ",", "5", ",", "1", ",", "4", | ||||||
|  |       ",", "0", ",", "0", ",", "9", ",", "3", ",", "2", ",", "0", ",", "4",  | ||||||
|  |      ",", "7"}], "}"}], ",", "1"}], "}"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.611271685319129*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{ | ||||||
|  |   RowBox[{"Graph", "[",  | ||||||
|  |    RowBox[{"Log", "[", "x", "]"}], "]"}], "\[IndentingNewLine]"}]], "Input", | ||||||
|  |  CellChangeTimes->{{3.611271689258354*^9, 3.611271702038085*^9}}], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"Graph", "[",  | ||||||
|  |   RowBox[{"Log", "[", "x", "]"}], "]"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.611271704295214*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[BoxData[""], "Input", | ||||||
|  |  CellChangeTimes->{{3.611271712769699*^9, 3.6112717423153887`*^9}}], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{ | ||||||
|  |   RowBox[{"Plot", "[",  | ||||||
|  |    RowBox[{ | ||||||
|  |     RowBox[{"Log", "[", "x", "]"}], ",", " ",  | ||||||
|  |     RowBox[{"{",  | ||||||
|  |      RowBox[{"x", ",", " ", "0", ",", " ", "10"}], "}"}]}], "]"}],  | ||||||
|  |   "\[IndentingNewLine]"}]], "Input", | ||||||
|  |  CellChangeTimes->{{3.6112717573482485`*^9, 3.6112717747822456`*^9}}], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  GraphicsBox[{{}, {},  | ||||||
|  |    {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" | ||||||
|  | 1:eJwVzXs81Pkex/GZH7XlsutSQprwqxTSZVfJGp9P6UYqlyxHUhTaLrq4JpVK | ||||||
|  | 0SHRisGWjYiEbHSvb+Q27rllmYwaY6JpwxgZTI7zx/vxejz/eht4H3PyoRgM | ||||||
|  | Rsj0/t+1MEPjP1Zc8O6L0tCYkJERTokxP5YLLR+MQy2qZWSzX62gWcaFn9s7 | ||||||
|  | 5sVFyohY4ZvLs5Ya6AheLQxnyIgFe4fllag6yH4zayhMcYw0FU5SRl8bweS/ | ||||||
|  | wyVFa0aJBsz2VDVrAl8V299DGKPk1yWJllEHmqD42vuI4RopiRvJlYS9bYLZ | ||||||
|  | a2c4j3pJyS8JbT7eeW/By6ht44vkEXKuxtRu1d4WOB5QmStjSUhO0eMleTda | ||||||
|  | 4EZtHmU5PEyaORsUFte1QFHRg6WjFcNkkZ/bC+11rVC0s8n9nf8wqVGINGNo | ||||||
|  | tkFRzD3HsYohosXu0misbAdxXml1VdQgKSi80nXErBNo/oP47aliMqAxEGvn | ||||||
|  | 1QlVgoRvezzExCjYznppYifkn+K6CVli8peV8m2BrBNM20LljlmfyXVurK97 | ||||||
|  | RRfcVCpPCXg8QIIF14a2eLyHn6Y4909//UTSlWsvqm/qge1fVjduzhISa/Zp | ||||||
|  | jwjPHvCM6ZD7BQgJz9/E/GtIDyRsSj3Svl5ItJtj+uru9cBdE2PXZH4vSeDY | ||||||
|  | 20arfYAT6Z3e8axecnFxw49TXR/gU5X5vDu5H4kfvE0RnxSAsqvDMcduPmFk | ||||||
|  | jD7rihGA7RmZ5qlYPuEo6vFq7gigR67QPetXPqnm+rJy2wUA0hVVHindZOmu | ||||||
|  | yQwfy17Y4OU185n7e/LpoNH9bqYQPPrPvwn+2kkOXT/zqim+DzJ72WEzdrcT | ||||||
|  | SprBJ7l9UD/Fag2c005SXasZhWV9kH51Z/aqhjZSo6dpc3WkD4L1tqolbGgj | ||||||
|  | JndzqmzdRPD67PLxVrNWIn7e0lS28BMs6Ba9FM1pJv7CZYLign6IeWFYmrqk | ||||||
|  | jvR4/jOrlNsPoqNsieZftcS5I9qsvrcf8tnmIzq6tcSiVnRKqDsALqbKTVU/ | ||||||
|  | 1RCFoiw1ragBULG3LYphVhNOuIF1yN7PkFMpYVXI35BSTZ2UdWpfgMls07e/ | ||||||
|  | 84QoGUQa8S0GgVn/55MIdixUWyWsOLtpEAIiTazYlglw2e3W2gVOg5BMOVFO | ||||||
|  | zolAxT/ZsvvwIJAvj7SczqbC+Hex37ubgxD8udJ0tkcmfOa55DRSQ8DwsFzc | ||||||
|  | 6lkIdRyjZa/rhsAywLBSze45xKnVGt/eJwFLB1UN7sVq8O7aRRTqRsFbq7Mr | ||||||
|  | JqcdTlREeh8zGoeOsKZ1bgF8KDqu4qxtK4c/T0q26boJ4PbpwwMrXRn4N9vd | ||||||
|  | qamzDy6kTzqOiJmo6OOuteZtPzBaevBFmALy6nNqfwkTw5JA39BdxjPwSH3B | ||||||
|  | vlWGX6FXmvyb8suZeCtkhRV5NAh2wkNnrp+YhaOXrkQMdg/Bjt54ExZLCdti | ||||||
|  | v+y2+XcYBt54R1TnKyOH4R+txpOAmXr7Apu9quiaByGbG0dACaRePMmPmLmw | ||||||
|  | vX84Swpbvrh/M3RRQziRFnP5wih0lB1gupuqY0FCbZyewzcoiS731JeqY4Zj | ||||||
|  | 3+qZP4yB74ygnoYGDcz5GOJ8uXwM9p88XaKSqonn9R26+EdlsMLPpMHeaw4K | ||||||
|  | rc1neaqOQ6OGqXLQurmYKexKyno4Ds8LLqSZKmhhhvxW6cjWCTjNNHaoe6+F | ||||||
|  | pidKHHi9E6DEC9vqXzwPGaH7eO6hkyDMNkhMD9fGsUD+Knv5JCQu1VF86qKD | ||||||
|  | h3vll15HyyE+1bfKS18XbTje/KqZ38E9cU+DikgXNYxUk++f/Q5jG7Nk6a/m | ||||||
|  | 49yHih6fJ7+DQLghtCxKD9We/pFtf2wKMtir5td7LcDHFdUyrmgK8i8Fqfst | ||||||
|  | Z2H5rdC2ZGMGRrns36YgZWHfc/sj7Z4MNOfdzo2qX4jaWiITpSQGcpal5ddv | ||||||
|  | 08c4nrYPVjPw3OurnG1P9ZGdfship5yB2+e7ZNUsMsAzD/MLtFcycb1/1W71 | ||||||
|  | Kwb4qn7LsIcnE9P1vBfVSQ1QUbd5z75rTFz05m7Sjt2GeHJ9UIrOCybGLy8z | ||||||
|  | bn5liLETFcsURUz0lSi+5RrTGL/GlX1jDoXeRcP6V67R6DRvQNHcmsIjF5wn | ||||||
|  | 7RJoPPVD0ph42kHOxe9U/qDR/97LrjtAYbQ0KC4+iUa6N+b4nPUUFqyTTSTf | ||||||
|  | pDFTFtw6bEOhrHSqPTuPRo1786Pv21IY36xytbyKxo0v5z7UdKEwNfPowctc | ||||||
|  | GuUeojTutDMDG2y21tIYpHQ98NxvFD7Sih+vbaBRfeZZ6YArhTx3zYMtbTRC | ||||||
|  | CmNNqTuFRgIdm48CGveGmxUf2kfhyuIw1h0hjasPiNIWelFoealL5iOiMZKf | ||||||
|  | HdA6bXujmw/6B2gk7zZK2PspPHlYnzU0RGN40raf1XwpDLc6L/tbMv0vikor | ||||||
|  | n/Yl1Y+tgVIayzZ/kIT6UcgpzIwZG6Px0d7RwA8HKcyIUPR7Nk7j8sLHN2/8 | ||||||
|  | TmGeo8+G8Ekab1ncfmR7iMJiw8oF1t9pnF9RQuTTfiVZIpuaonFCb+xJ0WEK | ||||||
|  | /wc13qzo | ||||||
|  |      "]]}}, | ||||||
|  |   AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], | ||||||
|  |   Axes->True, | ||||||
|  |   AxesLabel->{None, None}, | ||||||
|  |   AxesOrigin->{0, 0}, | ||||||
|  |   Method->{}, | ||||||
|  |   PlotRange->{{0, 10}, {-1.623796532045525, 2.3025850725858823`}}, | ||||||
|  |   PlotRangeClipping->True, | ||||||
|  |   PlotRangePadding->{ | ||||||
|  |     Scaled[0.02],  | ||||||
|  |     Scaled[0.02]}]], "Output", | ||||||
|  |  CellChangeTimes->{3.6112717778594217`*^9}] | ||||||
|  | }, Open  ]] | ||||||
|  | }, | ||||||
|  | WindowSize->{716, 833}, | ||||||
|  | WindowMargins->{{Automatic, 214}, {Automatic, 26}}, | ||||||
|  | FrontEndVersion->"9.0 for Microsoft Windows (64-bit) (January 25, 2013)", | ||||||
|  | StyleDefinitions->"Default.nb" | ||||||
|  | ] | ||||||
|  | (* End of Notebook Content *) | ||||||
|  |  | ||||||
|  | (* Internal cache information *) | ||||||
|  | (*CellTagsOutline | ||||||
|  | CellTagsIndex->{} | ||||||
|  | *) | ||||||
|  | (*CellTagsIndex | ||||||
|  | CellTagsIndex->{} | ||||||
|  | *) | ||||||
|  | (*NotebookFileOutline | ||||||
|  | Notebook[{ | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[579, 22, 224, 6, 52, "Input"], | ||||||
|  | Cell[806, 30, 211, 6, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[1054, 41, 155, 3, 31, "Input"], | ||||||
|  | Cell[1212, 46, 130, 3, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[1379, 54, 137, 4, 31, "Input"], | ||||||
|  | Cell[1519, 60, 105, 2, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[1661, 67, 113, 3, 31, "Input"], | ||||||
|  | Cell[1777, 72, 90, 1, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[1904, 78, 102, 2, 31, "Input"], | ||||||
|  | Cell[2009, 82, 321, 8, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[2367, 95, 191, 4, 52, "Input"], | ||||||
|  | Cell[2561, 101, 131, 3, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[2707, 107, 94, 1, 31, "Input"], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[2826, 112, 299, 8, 52, "Input"], | ||||||
|  | Cell[3128, 122, 3019, 57, 265, "Output"] | ||||||
|  | }, Open  ]] | ||||||
|  | } | ||||||
|  | ] | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | (* End of internal cache information *) | ||||||
							
								
								
									
										3666
									
								
								samples/Mathematica/MiscCalculations2.nb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3666
									
								
								samples/Mathematica/MiscCalculations2.nb
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										8
									
								
								samples/Mathematica/Problem12.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								samples/Mathematica/Problem12.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | (* ::Package:: *) | ||||||
|  |  | ||||||
|  | (* Problem12.m *) | ||||||
|  | (* Author: William Woodruff *) | ||||||
|  | (* Problem: What is the value of the first triangle number to have over five hundred divisors? *) | ||||||
|  |  | ||||||
|  | Do[If[Length[Divisors[Binomial[i + 1, 2]]] > 500,  | ||||||
|  |   Print[Binomial[i + 1, 2]]; Break[]], {i, 1000000}] | ||||||
							
								
								
									
										272
									
								
								samples/Nit/calculator.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								samples/Nit/calculator.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,272 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | import gtk | ||||||
|  |  | ||||||
|  | class CalculatorContext | ||||||
|  | 	var result : nullable Float = null | ||||||
|  |  | ||||||
|  | 	var last_op : nullable Char = null | ||||||
|  |  | ||||||
|  | 	var current : nullable Float = null | ||||||
|  | 	var after_point : nullable Int = null | ||||||
|  |  | ||||||
|  | 	fun push_op( op : Char ) | ||||||
|  | 	do | ||||||
|  | 		apply_last_op_if_any | ||||||
|  | 		if op == 'C' then | ||||||
|  | 			self.result = 0.0 | ||||||
|  | 			last_op = null | ||||||
|  | 		else | ||||||
|  | 			last_op = op # store for next push_op | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		# prepare next current | ||||||
|  | 		after_point = null | ||||||
|  | 		current = null | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun push_digit( digit : Int ) | ||||||
|  | 	do | ||||||
|  | 		var current = current | ||||||
|  | 		if current == null then current = 0.0 | ||||||
|  |  | ||||||
|  | 		var after_point = after_point | ||||||
|  | 		if after_point == null then | ||||||
|  | 			current = current * 10.0 + digit.to_f | ||||||
|  | 		else | ||||||
|  | 			current = current + digit.to_f * 10.0.pow(after_point.to_f) | ||||||
|  | 			self.after_point -= 1 | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		self.current = current | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun switch_to_decimals | ||||||
|  | 	do | ||||||
|  | 		if self.current == null then current = 0.0 | ||||||
|  | 		if after_point != null then return | ||||||
|  |  | ||||||
|  | 		after_point = -1 | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun apply_last_op_if_any | ||||||
|  | 	do | ||||||
|  | 		var op = last_op | ||||||
|  |  | ||||||
|  | 		var result = result | ||||||
|  | 		if result == null then result = 0.0 | ||||||
|  |  | ||||||
|  | 		var current = current | ||||||
|  | 		if current == null then current = 0.0 | ||||||
|  |  | ||||||
|  | 		if op == null then | ||||||
|  | 			result = current | ||||||
|  | 		else if op == '+' then | ||||||
|  | 			result = result + current | ||||||
|  | 		else if op == '-' then | ||||||
|  | 			result = result - current | ||||||
|  | 		else if op == '/' then | ||||||
|  | 			result = result / current | ||||||
|  | 		else if op == '*' then | ||||||
|  | 			result = result * current | ||||||
|  | 		end | ||||||
|  | 		self.result = result | ||||||
|  | 		self.current = null | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | class CalculatorGui | ||||||
|  | 	super GtkCallable | ||||||
|  |  | ||||||
|  | 	var win : GtkWindow | ||||||
|  | 	var container : GtkGrid | ||||||
|  |  | ||||||
|  | 	var lbl_disp : GtkLabel | ||||||
|  | 	var but_eq : GtkButton | ||||||
|  | 	var but_dot : GtkButton | ||||||
|  |  | ||||||
|  | 	var context = new CalculatorContext | ||||||
|  |  | ||||||
|  | 	redef fun signal( sender, user_data ) | ||||||
|  | 	do | ||||||
|  | 		var after_point = context.after_point | ||||||
|  | 		if after_point == null then  | ||||||
|  | 		    after_point = 0 | ||||||
|  | 		else | ||||||
|  | 		    after_point = (after_point.abs) | ||||||
|  | 		end | ||||||
|  | 		 | ||||||
|  | 		if user_data isa Char then # is an operation | ||||||
|  | 			var c = user_data | ||||||
|  | 			if c == '.' then | ||||||
|  | 				but_dot.sensitive= false | ||||||
|  | 				context.switch_to_decimals | ||||||
|  | 				lbl_disp.text = "{context.current.to_i}." | ||||||
|  | 			else | ||||||
|  | 				but_dot.sensitive= true | ||||||
|  | 				context.push_op( c ) | ||||||
|  | 				 | ||||||
|  | 				var s = context.result.to_precision_native(6) | ||||||
|  | 				var index : nullable Int = null | ||||||
|  | 				for i in s.length.times do | ||||||
|  | 				    var chiffre = s.chars[i] | ||||||
|  | 				    if chiffre == '0' and index == null then | ||||||
|  | 					index = i | ||||||
|  | 				    else if chiffre != '0' then | ||||||
|  | 					index = null | ||||||
|  | 				    end | ||||||
|  | 				end | ||||||
|  | 				if index != null then | ||||||
|  | 					s = s.substring(0, index) | ||||||
|  | 					if s.chars[s.length-1] == ',' then s = s.substring(0, s.length-1) | ||||||
|  | 				end | ||||||
|  | 				lbl_disp.text = s | ||||||
|  | 			end | ||||||
|  | 		else if user_data isa Int then # is a number | ||||||
|  | 			var n = user_data | ||||||
|  | 			context.push_digit( n ) | ||||||
|  | 			lbl_disp.text = context.current.to_precision_native(after_point) | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	init | ||||||
|  | 	do | ||||||
|  | 		init_gtk | ||||||
|  |  | ||||||
|  | 		win = new GtkWindow( 0 ) | ||||||
|  |  | ||||||
|  | 		container = new GtkGrid(5,5,true) | ||||||
|  | 		win.add( container ) | ||||||
|  |  | ||||||
|  | 		lbl_disp = new GtkLabel( "_" ) | ||||||
|  | 		container.attach( lbl_disp, 0, 0, 5, 1 ) | ||||||
|  |  | ||||||
|  | 		# digits | ||||||
|  | 		for n in [0..9] do | ||||||
|  | 			var but = new GtkButton.with_label( n.to_s ) | ||||||
|  | 			but.request_size( 64, 64 ) | ||||||
|  | 			but.signal_connect( "clicked", self, n ) | ||||||
|  | 			if n == 0 then | ||||||
|  | 				container.attach( but, 0, 4, 1, 1 ) | ||||||
|  | 			else container.attach( but, (n-1)%3, 3-(n-1)/3, 1, 1 ) | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		# operators | ||||||
|  | 		var r = 1 | ||||||
|  | 		for op in ['+', '-', '*', '/' ] do | ||||||
|  | 			var but = new GtkButton.with_label( op.to_s ) | ||||||
|  | 			but.request_size( 64, 64 ) | ||||||
|  | 			but.signal_connect( "clicked", self, op ) | ||||||
|  | 			container.attach( but, 3, r, 1, 1 ) | ||||||
|  | 			r+=1 | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		# = | ||||||
|  | 		but_eq = new GtkButton.with_label( "=" ) | ||||||
|  | 		but_eq.request_size( 64, 64 ) | ||||||
|  | 		but_eq.signal_connect( "clicked", self, '=' ) | ||||||
|  | 		container.attach( but_eq, 4, 3, 1, 2 ) | ||||||
|  |  | ||||||
|  | 		# . | ||||||
|  | 		but_dot = new GtkButton.with_label( "." ) | ||||||
|  | 		but_dot.request_size( 64, 64 ) | ||||||
|  | 		but_dot.signal_connect( "clicked", self, '.' ) | ||||||
|  | 		container.attach( but_dot, 1, 4, 1, 1 ) | ||||||
|  |  | ||||||
|  | 		#C | ||||||
|  | 		var but_c =  new GtkButton.with_label( "C" ) | ||||||
|  | 		but_c.request_size( 64, 64 ) | ||||||
|  | 		but_c.signal_connect("clicked", self, 'C') | ||||||
|  | 		container.attach( but_c, 2, 4, 1, 1 ) | ||||||
|  |  | ||||||
|  | 		win.show_all | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # context tests | ||||||
|  | var context = new CalculatorContext | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 2 ) | ||||||
|  | context.push_op( '+' ) | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '*' ) | ||||||
|  | context.push_digit( 2 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | var r = context.result.to_precision( 2 ) | ||||||
|  | assert r == "30.00" else print r | ||||||
|  |  | ||||||
|  | context = new CalculatorContext | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 4 ) | ||||||
|  | context.switch_to_decimals | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_op( '*' ) | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | r = context.result.to_precision( 2 ) | ||||||
|  | assert r == "42.30" else print r | ||||||
|  |  | ||||||
|  | context.push_op( '+' ) | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | r = context.result.to_precision( 2 ) | ||||||
|  | assert r == "53.30" else print r | ||||||
|  |  | ||||||
|  | context = new CalculatorContext | ||||||
|  | context.push_digit( 4 ) | ||||||
|  | context.push_digit( 2 ) | ||||||
|  | context.switch_to_decimals | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '/' ) | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | r = context.result.to_precision( 2 ) | ||||||
|  | assert r == "14.10" else print r | ||||||
|  |  | ||||||
|  | #test multiple decimals | ||||||
|  | context = new CalculatorContext | ||||||
|  | context.push_digit( 5 ) | ||||||
|  | context.push_digit( 0 ) | ||||||
|  | context.switch_to_decimals | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 2 ) | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '+' ) | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | r = context.result.to_precision( 3 ) | ||||||
|  | assert r == "51.123" else print r | ||||||
|  |  | ||||||
|  | #test 'C' button | ||||||
|  | context = new CalculatorContext | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 0 ) | ||||||
|  | context.push_op( '+' ) | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 0 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | context.push_op( 'C' ) | ||||||
|  | r = context.result.to_precision( 1 ) | ||||||
|  | assert r == "0.0" else print r | ||||||
|  |  | ||||||
|  | # graphical application | ||||||
|  |  | ||||||
|  | if "NIT_TESTING".environ != "true" then | ||||||
|  | 	var app = new CalculatorGui | ||||||
|  | 	run_gtk | ||||||
|  | end | ||||||
							
								
								
									
										45
									
								
								samples/Nit/callback_chimpanze.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								samples/Nit/callback_chimpanze.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This sample has been implemented to show you how simple is it to play  | ||||||
|  | # with native callbacks (C) through an high level with NIT program. | ||||||
|  |  | ||||||
|  | module callback_chimpanze | ||||||
|  | import callback_monkey | ||||||
|  |  | ||||||
|  | class Chimpanze | ||||||
|  | 	super MonkeyActionCallable | ||||||
|  |  | ||||||
|  | 	fun create | ||||||
|  | 	do | ||||||
|  | 		var monkey = new Monkey | ||||||
|  | 		print "Hum, I'm sleeping ..." | ||||||
|  | 		# Invoking method which will take some time to compute, and  | ||||||
|  | 		# will be back in wokeUp method with information. | ||||||
|  | 		# - Callback method defined in MonkeyActionCallable Interface | ||||||
|  | 		monkey.wokeUpAction(self, "Hey, I'm awake.") | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Inherit callback method, defined by MonkeyActionCallable interface | ||||||
|  | 	# - Back of wokeUpAction method  | ||||||
|  | 	redef fun wokeUp( sender:Monkey, message:Object ) | ||||||
|  | 	do | ||||||
|  | 		print message | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var m = new Chimpanze | ||||||
|  | m.create | ||||||
							
								
								
									
										92
									
								
								samples/Nit/callback_monkey.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								samples/Nit/callback_monkey.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This sample has been implemented to show you how simple is it to play  | ||||||
|  | # with native callbacks (C) through an high level with NIT program. | ||||||
|  |  | ||||||
|  | module callback_monkey | ||||||
|  |  | ||||||
|  | in "C header" `{ | ||||||
|  | 	#include <stdio.h> | ||||||
|  | 	#include <stdlib.h> | ||||||
|  |  | ||||||
|  | 	typedef struct {  | ||||||
|  | 		int id; | ||||||
|  | 		int age; | ||||||
|  | 	} CMonkey; | ||||||
|  |  | ||||||
|  | 	typedef struct { | ||||||
|  | 		MonkeyActionCallable toCall; | ||||||
|  | 		Object message; | ||||||
|  | 	} MonkeyAction; | ||||||
|  | `} | ||||||
|  |  | ||||||
|  | in "C body" `{ | ||||||
|  | 	// Method which reproduce a callback answer | ||||||
|  | 	// Please note that a function pointer is only used to reproduce the callback | ||||||
|  | 	void cbMonkey(CMonkey *mkey, void callbackFunc(CMonkey*, MonkeyAction*), MonkeyAction *data) | ||||||
|  | 	{ | ||||||
|  | 		sleep(2); | ||||||
|  | 		callbackFunc( mkey, data ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Back of background treatment, will be redirected to callback function | ||||||
|  | 	void nit_monkey_callback_func( CMonkey *mkey, MonkeyAction *data ) | ||||||
|  | 	{ | ||||||
|  | 		// To call a your method, the signature must be written like this : | ||||||
|  | 		// <Interface Name>_<Method>... | ||||||
|  | 		MonkeyActionCallable_wokeUp( data->toCall, mkey, data->message ); | ||||||
|  | 	} | ||||||
|  | `} | ||||||
|  |  | ||||||
|  | # Implementable interface to get callback in defined methods | ||||||
|  | interface MonkeyActionCallable | ||||||
|  | 	fun wokeUp( sender:Monkey, message: Object) is abstract | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Defining my object type Monkey, which is, in a low level, a pointer to a C struct (CMonkey) | ||||||
|  | extern class Monkey `{ CMonkey * `} | ||||||
|  | 	 | ||||||
|  | 	new `{ | ||||||
|  | 		CMonkey *monkey = malloc( sizeof(CMonkey) ); | ||||||
|  | 		monkey->age = 10; | ||||||
|  | 		monkey->id = 1; | ||||||
|  | 		return monkey; | ||||||
|  | 	`} | ||||||
|  | 	 | ||||||
|  | 	# Object method which will get a callback in wokeUp method, defined in MonkeyActionCallable interface | ||||||
|  | 	# Must be defined as Nit/C method because of C call inside | ||||||
|  | 	fun wokeUpAction( toCall: MonkeyActionCallable, message: Object ) is extern import MonkeyActionCallable.wokeUp `{ | ||||||
|  |  | ||||||
|  | 		// Allocating memory to keep reference of received parameters : | ||||||
|  | 		// - Object receiver | ||||||
|  | 		// - Message  | ||||||
|  | 		MonkeyAction *data = malloc( sizeof(MonkeyAction) ); | ||||||
|  |  | ||||||
|  | 		// Incrementing reference counter to prevent from releasing | ||||||
|  | 		MonkeyActionCallable_incr_ref( toCall ); | ||||||
|  | 		Object_incr_ref( message ); | ||||||
|  | 		 | ||||||
|  | 		data->toCall = toCall; | ||||||
|  | 		data->message = message; | ||||||
|  | 		 | ||||||
|  | 		// Calling method which reproduce a callback by passing : | ||||||
|  | 		// - Receiver | ||||||
|  | 		// - Function pointer to object return method | ||||||
|  | 		// - Datas | ||||||
|  | 		cbMonkey( recv, &nit_monkey_callback_func, data ); | ||||||
|  | 	`} | ||||||
|  | end | ||||||
							
								
								
									
										167
									
								
								samples/Nit/circular_list.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								samples/Nit/circular_list.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Implementation of circular lists | ||||||
|  | # This example shows the usage of generics and somewhat a specialisation of collections. | ||||||
|  | module circular_list | ||||||
|  |  | ||||||
|  | # Sequences of elements implemented with a double-linked circular list | ||||||
|  | class CircularList[E] | ||||||
|  | 	# Like standard Array or LinkedList, CircularList is a Sequence. | ||||||
|  | 	super Sequence[E] | ||||||
|  |  | ||||||
|  | 	# The first node of the list if any | ||||||
|  | 	# The special case of an empty list is handled by a null node | ||||||
|  | 	private var node: nullable CLNode[E] = null | ||||||
|  |  | ||||||
|  | 	redef fun iterator do return new CircularListIterator[E](self) | ||||||
|  |  | ||||||
|  | 	redef fun first do return self.node.item | ||||||
|  |  | ||||||
|  | 	redef fun push(e) | ||||||
|  | 	do | ||||||
|  | 		var new_node = new CLNode[E](e) | ||||||
|  | 		var n = self.node | ||||||
|  | 		if n == null then | ||||||
|  | 			# the first node | ||||||
|  | 			self.node = new_node | ||||||
|  | 		else | ||||||
|  | 			# not the first one, so attach nodes correctly. | ||||||
|  | 			var old_last_node = n.prev | ||||||
|  | 			new_node.next = n | ||||||
|  | 			new_node.prev = old_last_node | ||||||
|  | 			old_last_node.next = new_node | ||||||
|  | 			n.prev = new_node | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun pop | ||||||
|  | 	do | ||||||
|  | 		var n = self.node | ||||||
|  | 		assert n != null | ||||||
|  | 		var prev = n.prev | ||||||
|  | 		if prev == n then | ||||||
|  | 			# the only node | ||||||
|  | 			self.node = null | ||||||
|  | 			return n.item | ||||||
|  | 		end | ||||||
|  | 		# not the only one do detach nodes correctly. | ||||||
|  | 		var prev_prev = prev.prev | ||||||
|  | 		n.prev = prev_prev | ||||||
|  | 		prev_prev.next = n | ||||||
|  | 		return prev.item | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun unshift(e) | ||||||
|  | 	do | ||||||
|  | 		# Circularity has benefits. | ||||||
|  | 		push(e) | ||||||
|  | 		self.node = self.node.prev | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun shift | ||||||
|  | 	do | ||||||
|  | 		# Circularity has benefits. | ||||||
|  | 		self.node = self.node.next | ||||||
|  | 		return self.pop | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Move the first at the last position, the second at the first, etc. | ||||||
|  | 	fun rotate | ||||||
|  | 	do | ||||||
|  | 		var n = self.node | ||||||
|  | 		if n == null then return | ||||||
|  | 		self.node = n.next | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Sort the list using the Josephus algorithm. | ||||||
|  | 	fun josephus(step: Int) | ||||||
|  | 	do | ||||||
|  | 		var res = new CircularList[E] | ||||||
|  | 		while not self.is_empty do | ||||||
|  | 			# count 'step' | ||||||
|  | 			for i in [1..step[ do self.rotate | ||||||
|  | 			# kill | ||||||
|  | 			var x = self.shift | ||||||
|  | 			res.add(x) | ||||||
|  | 		end | ||||||
|  | 		self.node = res.node | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Nodes of a CircularList | ||||||
|  | private class CLNode[E] | ||||||
|  | 	# The current item | ||||||
|  | 	var item: E | ||||||
|  |  | ||||||
|  | 	# The next item in the circular list. | ||||||
|  | 	# Because of circularity, there is always a next; | ||||||
|  | 	# so by default let it be self | ||||||
|  | 	var next: CLNode[E] = self | ||||||
|  |  | ||||||
|  | 	# The previous item in the circular list. | ||||||
|  | 	# Coherence between next and previous nodes has to be maintained by the | ||||||
|  | 	# circular list. | ||||||
|  | 	var prev: CLNode[E] = self | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # An iterator of a CircularList. | ||||||
|  | private class CircularListIterator[E] | ||||||
|  | 	super IndexedIterator[E] | ||||||
|  |  | ||||||
|  | 	redef var index: Int | ||||||
|  |  | ||||||
|  | 	# The current node pointed. | ||||||
|  | 	# Is null if the list is empty. | ||||||
|  | 	var node: nullable CLNode[E] | ||||||
|  |  | ||||||
|  | 	# The list iterated. | ||||||
|  | 	var list: CircularList[E] | ||||||
|  |  | ||||||
|  | 	redef fun is_ok | ||||||
|  | 	do | ||||||
|  | 		# Empty lists are not OK. | ||||||
|  | 		# Pointing again the first node is not OK. | ||||||
|  | 		return self.node != null and (self.index == 0 or self.node != self.list.node) | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun next | ||||||
|  | 	do | ||||||
|  | 		self.node = self.node.next | ||||||
|  | 		self.index += 1 | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun item do return self.node.item | ||||||
|  |  | ||||||
|  | 	init(list: CircularList[E]) | ||||||
|  | 	do | ||||||
|  | 		self.node = list.node | ||||||
|  | 		self.list = list | ||||||
|  | 		self.index = 0 | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var i = new CircularList[Int] | ||||||
|  | i.add_all([1, 2, 3, 4, 5, 6, 7]) | ||||||
|  | print i.first | ||||||
|  | print i.join(":") | ||||||
|  |  | ||||||
|  | i.push(8) | ||||||
|  | print i.shift | ||||||
|  | print i.pop | ||||||
|  | i.unshift(0) | ||||||
|  | print i.join(":") | ||||||
|  |  | ||||||
|  | i.josephus(3) | ||||||
|  | print i.join(":") | ||||||
							
								
								
									
										78
									
								
								samples/Nit/clock.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								samples/Nit/clock.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This module provide a simple wall clock. | ||||||
|  | # It is an example of getters and setters. | ||||||
|  | # A beefed-up module is available in clock_more | ||||||
|  | module clock | ||||||
|  |  | ||||||
|  | # A simple wall clock with 60 minutes and 12 hours. | ||||||
|  | class Clock | ||||||
|  | 	# total number of minutes from 0 to 719 | ||||||
|  | 	var total_minutes: Int | ||||||
|  | 	# Note: only the read acces is public, the write access is private. | ||||||
|  |  | ||||||
|  | 	# number of minutes in the current hour (from 0 to 59) | ||||||
|  | 	fun minutes: Int do return self.total_minutes % 60 | ||||||
|  | 	 | ||||||
|  | 	# set the number of minutes in the current hour. | ||||||
|  | 	# if m < 0 or m >= 60, the hour will be changed accordinlgy | ||||||
|  | 	fun minutes=(m: Int) do self.total_minutes = self.hours * 60 + m | ||||||
|  |  | ||||||
|  | 	# number of hours (from 0 to 11) | ||||||
|  | 	fun hours: Int do return self.total_minutes / 60 | ||||||
|  |  | ||||||
|  | 	# set the number of hours | ||||||
|  | 	# the minutes will not be updated | ||||||
|  | 	fun hours=(h: Int) do self.total_minutes = h * 60 + minutes | ||||||
|  |  | ||||||
|  | 	# the position of the hour arrow in the [0..60[ interval | ||||||
|  | 	fun hour_pos: Int do return total_minutes / 12 | ||||||
|  |  | ||||||
|  | 	# replace the arrow of hours (from 0 to 59). | ||||||
|  | 	# the hours and the minutes will be updated. | ||||||
|  | 	fun hour_pos=(h: Int) do self.total_minutes = h * 12 | ||||||
|  |  | ||||||
|  | 	redef fun to_s do return "{hours}:{minutes}" | ||||||
|  |  | ||||||
|  | 	fun reset(hours, minutes: Int) do self.total_minutes = hours*60 + minutes | ||||||
|  |  | ||||||
|  | 	init(hours, minutes: Int) do self.reset(hours, minutes) | ||||||
|  |  | ||||||
|  | 	redef fun ==(o) | ||||||
|  | 	do | ||||||
|  | 		# Note: o is a nullable Object, a type test is required | ||||||
|  | 		# Thanks to adaptive typing, there is no downcast | ||||||
|  | 		# i.e. the code is safe! | ||||||
|  | 		return o isa Clock and self.total_minutes == o.total_minutes | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var c = new Clock(10,50) | ||||||
|  | print "It's {c} o'clock." | ||||||
|  |  | ||||||
|  | c.minutes += 22 | ||||||
|  | print "Now it's {c} o'clock." | ||||||
|  |  | ||||||
|  | print "The short arrow in on the {c.hour_pos/5} and the long arrow in on the {c.minutes/5}." | ||||||
|  |  | ||||||
|  | c.hours -= 2 | ||||||
|  | print "Now it's {c} o'clock." | ||||||
|  |  | ||||||
|  | var c2 = new Clock(9, 11) | ||||||
|  | print "It's {c2} on the second clock." | ||||||
|  | print "The two clocks are synchronized: {c == c2}." | ||||||
|  | c2.minutes += 1 | ||||||
|  | print "It's now {c2} on the second clock." | ||||||
|  | print "The two clocks are synchronized: {c == c2}." | ||||||
							
								
								
									
										60
									
								
								samples/Nit/clock_more.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								samples/Nit/clock_more.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This module beef up the clock module by allowing a clock to be comparable. | ||||||
|  | # It show the usage of class refinement | ||||||
|  | module clock_more | ||||||
|  |  | ||||||
|  | import clock | ||||||
|  |  | ||||||
|  | redef class Clock | ||||||
|  | 	# Clock are now comparable | ||||||
|  | 	super Comparable | ||||||
|  |  | ||||||
|  | 	# Comparaison of a clock make only sense with an other clock | ||||||
|  | 	redef type OTHER: Clock | ||||||
|  |  | ||||||
|  | 	redef fun <(o) | ||||||
|  | 	do | ||||||
|  | 		# Note: < is the only abstract method of Comparable. | ||||||
|  | 		#       All other operators and methods rely on < and ==. | ||||||
|  | 		return self.total_minutes < o.total_minutes | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var c1 = new Clock(8, 12) | ||||||
|  | var c2 = new Clock(8, 13) | ||||||
|  | var c3 = new Clock(9, 13) | ||||||
|  |  | ||||||
|  | print "{c1}<{c2}? {c1<c2}" | ||||||
|  | print "{c1}<={c2}? {c1<=c2}" | ||||||
|  | print "{c1}>{c2}? {c1>c2}" | ||||||
|  | print "{c1}>={c2}? {c1>=c2}" | ||||||
|  | print "{c1}<=>{c2}? {c1<=>c2}" | ||||||
|  | print "{c1},{c2}? max={c1.max(c2)} min={c1.min(c2)}" | ||||||
|  | print "{c1}.is_between({c2}, {c3})? {c1.is_between(c2, c3)}" | ||||||
|  | print "{c2}.is_between({c1}, {c3})? {c2.is_between(c1, c3)}" | ||||||
|  |  | ||||||
|  | print "-" | ||||||
|  |  | ||||||
|  | c1.minutes += 1 | ||||||
|  |  | ||||||
|  | print "{c1}<{c2}? {c1<c2}" | ||||||
|  | print "{c1}<={c2}? {c1<=c2}" | ||||||
|  | print "{c1}>{c2}? {c1>c2}" | ||||||
|  | print "{c1}>={c2}? {c1>=c2}" | ||||||
|  | print "{c1}<=>{c2}? {c1<=>c2}" | ||||||
|  | print "{c1},{c2}? max={c1.max(c2)} min={c1.min(c2)}" | ||||||
|  | print "{c1}.is_between({c2}, {c3})? {c1.is_between(c2, c3)}" | ||||||
|  | print "{c2}.is_between({c1}, {c3})? {c2.is_between(c1, c3)}" | ||||||
							
								
								
									
										113
									
								
								samples/Nit/curl_http.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								samples/Nit/curl_http.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Sample of the Curl module. | ||||||
|  | module curl_http | ||||||
|  |  | ||||||
|  | import curl | ||||||
|  |  | ||||||
|  | # Small class to represent an Http Fetcher | ||||||
|  | class MyHttpFetcher | ||||||
|  | 	super CurlCallbacks | ||||||
|  |  | ||||||
|  | 	var curl: Curl | ||||||
|  | 	var our_body: String = "" | ||||||
|  |  | ||||||
|  | 	init(curl: Curl) do self.curl = curl | ||||||
|  |  | ||||||
|  | 	# Release curl object | ||||||
|  | 	fun destroy do self.curl.destroy | ||||||
|  |  | ||||||
|  | 	# Header callback | ||||||
|  | 	redef fun header_callback(line: String) do | ||||||
|  | 		# We keep this callback silent for testing purposes | ||||||
|  | 		#if not line.has_prefix("Date:") then print "Header_callback : {line}" | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Body callback | ||||||
|  | 	redef fun body_callback(line: String) do self.our_body = "{self.our_body}{line}" | ||||||
|  |  | ||||||
|  | 	# Stream callback - Cf : No one is registered | ||||||
|  | 	redef fun stream_callback(buffer: String, size: Int, count: Int) do print "Stream_callback : {buffer} - {size} - {count}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Program | ||||||
|  | if args.length < 2 then | ||||||
|  | 	print "Usage: curl_http <method wished [POST, GET, GET_FILE]> <target url>" | ||||||
|  | else | ||||||
|  | 	var curl = new Curl | ||||||
|  | 	var url = args[1] | ||||||
|  | 	var request = new CurlHTTPRequest(url, curl) | ||||||
|  |  | ||||||
|  | 	# HTTP Get Request | ||||||
|  | 	if args[0] == "GET" then | ||||||
|  | 		request.verbose = false | ||||||
|  | 		var getResponse = request.execute | ||||||
|  |  | ||||||
|  | 		if getResponse isa CurlResponseSuccess then | ||||||
|  | 			print "Status code : {getResponse.status_code}" | ||||||
|  | 			print "Body : {getResponse.body_str}" | ||||||
|  | 		else if getResponse isa CurlResponseFailed then | ||||||
|  | 			print "Error code : {getResponse.error_code}" | ||||||
|  | 			print "Error msg : {getResponse.error_msg}" | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 	# HTTP Post Request | ||||||
|  | 	else if args[0] == "POST" then | ||||||
|  | 		var myHttpFetcher = new MyHttpFetcher(curl) | ||||||
|  | 		request.delegate = myHttpFetcher | ||||||
|  |  | ||||||
|  | 		var postDatas = new HeaderMap | ||||||
|  | 		postDatas["Bugs Bunny"] = "Daffy Duck" | ||||||
|  | 		postDatas["Batman"] = "Robin likes special characters @#ùà!è§'(\"é&://,;<>∞~*" | ||||||
|  | 		postDatas["Batman"] = "Yes you can set multiple identical keys, but APACHE will consider only once, the last one" | ||||||
|  | 		request.datas = postDatas | ||||||
|  | 		request.verbose = false | ||||||
|  | 		var postResponse = request.execute | ||||||
|  |  | ||||||
|  | 		print "Our body from the callback : {myHttpFetcher.our_body}" | ||||||
|  |  | ||||||
|  | 		if postResponse isa CurlResponseSuccess then | ||||||
|  | 			print "*** Answer ***" | ||||||
|  | 			print "Status code : {postResponse.status_code}" | ||||||
|  | 			print "Body should be empty, because we decided to manage callbacks : {postResponse.body_str.length}" | ||||||
|  | 		else if postResponse isa CurlResponseFailed then | ||||||
|  | 			print "Error code : {postResponse.error_code}" | ||||||
|  | 			print "Error msg : {postResponse.error_msg}" | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 	# HTTP Get to file Request | ||||||
|  | 	else if args[0] == "GET_FILE" then | ||||||
|  | 		var headers = new HeaderMap | ||||||
|  | 		headers["Accept"] = "Moo" | ||||||
|  | 		request.headers = headers | ||||||
|  | 		request.verbose = false | ||||||
|  | 		var downloadResponse = request.download_to_file(null) | ||||||
|  |  | ||||||
|  | 		if downloadResponse isa CurlFileResponseSuccess then | ||||||
|  | 			print "*** Answer ***" | ||||||
|  | 			print "Status code : {downloadResponse.status_code}" | ||||||
|  | 			print "Size downloaded : {downloadResponse.size_download}" | ||||||
|  | 		else if downloadResponse isa CurlResponseFailed then | ||||||
|  | 			print "Error code : {downloadResponse.error_code}" | ||||||
|  | 			print "Error msg : {downloadResponse.error_msg}" | ||||||
|  | 		end | ||||||
|  | 	# Program logic | ||||||
|  | 	else | ||||||
|  | 		print "Usage : Method[POST, GET, GET_FILE]" | ||||||
|  | 	end | ||||||
|  | end | ||||||
							
								
								
									
										59
									
								
								samples/Nit/curl_mail.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								samples/Nit/curl_mail.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Mail sender sample using the Curl module | ||||||
|  | module curl_mail | ||||||
|  |  | ||||||
|  | import curl | ||||||
|  |  | ||||||
|  | var curl = new Curl | ||||||
|  | var mail_request = new CurlMailRequest(curl) | ||||||
|  |  | ||||||
|  | # Networks | ||||||
|  | var response = mail_request.set_outgoing_server("smtps://smtp.example.org:465", "user@example.org", "mypassword") | ||||||
|  | if response isa CurlResponseFailed then | ||||||
|  | 	print "Error code : {response.error_code}" | ||||||
|  | 	print "Error msg : {response.error_msg}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Headers | ||||||
|  | mail_request.from = "Billy Bob" | ||||||
|  | mail_request.to = ["user@example.org"] | ||||||
|  | mail_request.cc = ["bob@example.org"] | ||||||
|  | mail_request.bcc = null | ||||||
|  |  | ||||||
|  | var headers_body = new HeaderMap | ||||||
|  | headers_body["Content-Type:"] = "text/html; charset=\"UTF-8\"" | ||||||
|  | headers_body["Content-Transfer-Encoding:"] = "quoted-printable" | ||||||
|  | mail_request.headers_body = headers_body | ||||||
|  |  | ||||||
|  | # Content | ||||||
|  | mail_request.body = "<h1>Here you can write HTML stuff.</h1>" | ||||||
|  | mail_request.subject = "Hello From My Nit Program" | ||||||
|  |  | ||||||
|  | # Others | ||||||
|  | mail_request.verbose = false | ||||||
|  |  | ||||||
|  | # Send mail | ||||||
|  | response = mail_request.execute | ||||||
|  | if response isa CurlResponseFailed then | ||||||
|  | 	print "Error code : {response.error_code}" | ||||||
|  | 	print "Error msg : {response.error_msg}" | ||||||
|  | else if response isa CurlMailResponseSuccess then | ||||||
|  | 	print "Mail Sent" | ||||||
|  | else | ||||||
|  | 	print "Unknown Curl Response type" | ||||||
|  | end | ||||||
							
								
								
									
										243
									
								
								samples/Nit/draw_operation.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								samples/Nit/draw_operation.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,243 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Draws an arithmetic operation to the terminal | ||||||
|  | module draw_operation | ||||||
|  |  | ||||||
|  | redef enum Int | ||||||
|  | 	fun n_chars: Int `{ | ||||||
|  | 		int c; | ||||||
|  | 		if ( abs(recv) >= 10 ) | ||||||
|  | 			c = 1+(int)log10f( (float)abs(recv) ); | ||||||
|  | 		else | ||||||
|  | 			c = 1; | ||||||
|  | 		if ( recv < 0 ) c ++; | ||||||
|  | 		return c; | ||||||
|  | 	`} | ||||||
|  | end | ||||||
|  |  | ||||||
|  | redef enum Char | ||||||
|  | 	fun as_operator(a, b: Int): Int | ||||||
|  | 	do | ||||||
|  | 		if self == '+' then return a + b | ||||||
|  | 		if self == '-' then return a - b | ||||||
|  | 		if self == '*' then return a * b | ||||||
|  | 		if self == '/' then return a / b | ||||||
|  | 		if self == '%' then return a % b | ||||||
|  | 		abort | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun override_dispc: Bool | ||||||
|  | 	do | ||||||
|  | 		return self == '+' or self == '-' or self == '*' or self == '/' or self == '%' | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun lines(s: Int): Array[Line] | ||||||
|  | 	do | ||||||
|  | 		if self == '+' then | ||||||
|  | 			return [new Line(new P(0,s/2),1,0,s), new Line(new P(s/2,1),0,1,s-2)] | ||||||
|  | 		else if self == '-' then | ||||||
|  | 			return [new Line(new P(0,s/2),1,0,s)] | ||||||
|  | 		else if self == '*' then | ||||||
|  | 			var lines = new Array[Line] | ||||||
|  | 			for y in [1..s-1[ do | ||||||
|  | 				lines.add( new Line(new P(1,y), 1,0,s-2) ) | ||||||
|  | 			end | ||||||
|  | 			return lines | ||||||
|  | 		else if self == '/' then | ||||||
|  | 			return [new Line(new P(s-1,0), -1,1, s )] | ||||||
|  | 		else if self == '%' then | ||||||
|  | 			var q4 = s/4 | ||||||
|  | 			var lines = [new Line(new P(s-1,0),-1,1,s)] | ||||||
|  | 			for l in [0..q4[ do | ||||||
|  | 				lines.append([ new Line( new P(0,l), 1,0,q4), new Line( new P(s-1,s-1-l), -1,0,q4) ]) | ||||||
|  | 			end | ||||||
|  | 			return lines | ||||||
|  | 		else if self == '1' then | ||||||
|  | 			return [new Line(new P(s/2,0), 0,1,s),new Line(new P(0,s-1),1,0,s), | ||||||
|  | 				new Line( new P(s/2,0),-1,1,s/2)] | ||||||
|  | 		else if self == '2' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s/2), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 0,1,s/2), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '3' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '4' then | ||||||
|  | 			return [new Line(new P(s-1,0),0,1,s), new Line( new P(0,0), 0,1,s/2), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '5' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '6' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '7' then | ||||||
|  | 			var tl = new P(0,0) | ||||||
|  | 			var tr = new P(s-1,0) | ||||||
|  | 			return [new Line(tl, 1,0,s), new Line(tr,-1,1,s)] | ||||||
|  | 		else if self == '8' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '9' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '0' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s)] | ||||||
|  | 		end | ||||||
|  | 		return new Array[Line] | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | class P | ||||||
|  | 	var x : Int | ||||||
|  | 	var y : Int | ||||||
|  | end | ||||||
|  |  | ||||||
|  | redef class String | ||||||
|  | 	# hack is to support a bug in the evaluation software | ||||||
|  | 	fun draw(dispc: Char, size, gap: Int, hack: Bool) | ||||||
|  | 	do | ||||||
|  | 		var w = size * length +(length-1)*gap | ||||||
|  | 		var h = size | ||||||
|  | 		var map = new Array[Array[Char]] | ||||||
|  | 		for x in [0..w[ do | ||||||
|  | 			map[x] = new Array[Char].filled_with( ' ',  h ) | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		var ci = 0 | ||||||
|  | 		for c in self.chars do | ||||||
|  | 			var local_dispc | ||||||
|  | 			if c.override_dispc then | ||||||
|  | 				local_dispc = c | ||||||
|  | 			else | ||||||
|  | 				local_dispc = dispc | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			var lines = c.lines( size ) | ||||||
|  | 			for line in lines do | ||||||
|  | 				var x = line.o.x+ci*size | ||||||
|  | 					x += ci*gap | ||||||
|  | 				var y = line.o.y | ||||||
|  | 				for s in [0..line.len[ do | ||||||
|  | 					assert map.length > x and map[x].length > y else print "setting {x},{y} as {local_dispc}" | ||||||
|  | 					map[x][y] = local_dispc | ||||||
|  | 					x += line.step_x | ||||||
|  | 					y += line.step_y | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			ci += 1 | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		if hack then | ||||||
|  | 			for c in [0..size[ do | ||||||
|  | 				map[c][0] = map[map.length-size+c][0] | ||||||
|  | 				map[map.length-size+c][0] = ' ' | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		for y in [0..h[ do | ||||||
|  | 			for x in [0..w[ do | ||||||
|  | 				printn map[x][y] | ||||||
|  | 			end | ||||||
|  | 			print "" | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | class Line | ||||||
|  | 	var o : P | ||||||
|  | 	var step_x : Int | ||||||
|  | 	var step_y : Int | ||||||
|  | 	var len : Int | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var a | ||||||
|  | var b | ||||||
|  | var op_char | ||||||
|  | var disp_char | ||||||
|  | var disp_size | ||||||
|  | var disp_gap | ||||||
|  |  | ||||||
|  | if "NIT_TESTING".environ == "true" then | ||||||
|  | 	a = 567 | ||||||
|  | 	b = 13 | ||||||
|  | 	op_char = '*' | ||||||
|  | 	disp_char = 'O' | ||||||
|  | 	disp_size = 8 | ||||||
|  | 	disp_gap = 1 | ||||||
|  | else | ||||||
|  | 	printn "Left operand: " | ||||||
|  | 	a = gets.to_i | ||||||
|  |  | ||||||
|  | 	printn "Right operand: " | ||||||
|  | 	b = gets.to_i | ||||||
|  |  | ||||||
|  | 	printn "Operator (+, -, *, /, %): " | ||||||
|  | 	op_char = gets.chars[0] | ||||||
|  |  | ||||||
|  | 	printn "Char to display: " | ||||||
|  | 	disp_char = gets.chars[0] | ||||||
|  |  | ||||||
|  | 	printn "Size of text: " | ||||||
|  | 	disp_size = gets.to_i | ||||||
|  |  | ||||||
|  | 	printn "Space between digits: " | ||||||
|  | 	disp_gap = gets.to_i | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var result = op_char.as_operator( a, b ) | ||||||
|  |  | ||||||
|  | var len_a = a.n_chars | ||||||
|  | var len_b = b.n_chars | ||||||
|  | var len_res = result.n_chars | ||||||
|  | var max_len = len_a.max( len_b.max( len_res ) ) + 1 | ||||||
|  |  | ||||||
|  | # draw first line | ||||||
|  | var d = max_len - len_a | ||||||
|  | var line_a = "" | ||||||
|  | for i in [0..d[ do line_a += " " | ||||||
|  | line_a += a.to_s | ||||||
|  | line_a.draw( disp_char, disp_size, disp_gap, false ) | ||||||
|  |  | ||||||
|  | print "" | ||||||
|  | # draw second line | ||||||
|  | d = max_len - len_b-1 | ||||||
|  | var line_b = op_char.to_s | ||||||
|  | for i in [0..d[ do line_b += " " | ||||||
|  | line_b += b.to_s | ||||||
|  | line_b.draw( disp_char, disp_size, disp_gap, false ) | ||||||
|  |  | ||||||
|  | # draw ----- | ||||||
|  | print "" | ||||||
|  | for i in [0..disp_size*max_len+(max_len-1)*disp_gap] do | ||||||
|  | 	printn "_" | ||||||
|  | end | ||||||
|  | print "" | ||||||
|  | print "" | ||||||
|  |  | ||||||
|  | # draw result | ||||||
|  | d = max_len - len_res | ||||||
|  | var line_res = "" | ||||||
|  | for i in [0..d[ do line_res += " " | ||||||
|  | line_res += result.to_s | ||||||
|  | line_res.draw( disp_char, disp_size, disp_gap, false ) | ||||||
							
								
								
									
										46
									
								
								samples/Nit/drop_privileges.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								samples/Nit/drop_privileges.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Example using the privileges module to drop privileges from root | ||||||
|  | module drop_privileges | ||||||
|  |  | ||||||
|  | import privileges | ||||||
|  |  | ||||||
|  | # basic command line options | ||||||
|  | var opts = new OptionContext | ||||||
|  | var opt_ug = new OptionUserAndGroup.for_dropping_privileges | ||||||
|  | opt_ug.mandatory = true | ||||||
|  | opts.add_option(opt_ug) | ||||||
|  |  | ||||||
|  | # parse and check command line options | ||||||
|  | opts.parse(args) | ||||||
|  | if not opts.errors.is_empty then | ||||||
|  | 	print opts.errors | ||||||
|  | 	print "Usage: drop_privileges [options]" | ||||||
|  | 	opts.usage | ||||||
|  | 	exit 1 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # original user | ||||||
|  | print "before {sys.uid}:{sys.gid}" | ||||||
|  |  | ||||||
|  | # make the switch | ||||||
|  | var user_group = opt_ug.value | ||||||
|  | assert user_group != null | ||||||
|  | user_group.drop_privileges | ||||||
|  |  | ||||||
|  | # final user | ||||||
|  | print "after {sys.uid}:{sys.egid}" | ||||||
							
								
								
									
										69
									
								
								samples/Nit/extern_methods.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								samples/Nit/extern_methods.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This module illustrates some uses of the FFI, specifically | ||||||
|  | # how to use extern methods. Which means to implement a Nit method in C. | ||||||
|  | module extern_methods | ||||||
|  |  | ||||||
|  | redef enum Int | ||||||
|  | 	# Returns self'th fibonnaci number | ||||||
|  | 	# implemented here in C for optimization purposes | ||||||
|  | 	fun fib : Int import fib `{ | ||||||
|  | 		if ( recv < 2 ) | ||||||
|  | 			return recv; | ||||||
|  | 		else | ||||||
|  | 			return Int_fib( recv-1 ) + Int_fib( recv-2 ); | ||||||
|  | 	`} | ||||||
|  |  | ||||||
|  | 	# System call to sleep for "self" seconds | ||||||
|  | 	fun sleep `{ | ||||||
|  | 		sleep( recv ); | ||||||
|  | 	`} | ||||||
|  |  | ||||||
|  | 	# Return atan2l( self, x ) from libmath | ||||||
|  | 	fun atan_with( x : Int ) : Float `{ | ||||||
|  | 		return atan2( recv, x ); | ||||||
|  | 	`} | ||||||
|  |  | ||||||
|  | 	# This method callback to Nit methods from C code | ||||||
|  | 	# It will use from C code: | ||||||
|  | 	# * the local fib method | ||||||
|  | 	# * the + operator, a method of Int | ||||||
|  | 	# * to_s, a method of all objects | ||||||
|  | 	# * String.to_cstring, a method of String to return an equivalent char* | ||||||
|  | 	fun foo import fib, +, to_s, String.to_cstring `{ | ||||||
|  | 		long recv_fib = Int_fib( recv ); | ||||||
|  | 		long recv_plus_fib = Int__plus( recv, recv_fib ); | ||||||
|  |  | ||||||
|  | 		String nit_string = Int_to_s( recv_plus_fib ); | ||||||
|  | 		char *c_string = String_to_cstring( nit_string ); | ||||||
|  |  | ||||||
|  | 		printf( "from C: self + fib(self) = %s\n", c_string ); | ||||||
|  | 	`} | ||||||
|  |  | ||||||
|  | 	# Equivalent to foo but written in pure Nit | ||||||
|  | 	fun bar do print "from Nit: self + fib(self) = {self+self.fib}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | print 12.fib | ||||||
|  |  | ||||||
|  | print "sleeping 1 second..." | ||||||
|  | 1.sleep | ||||||
|  |  | ||||||
|  | print 100.atan_with( 200 ) | ||||||
|  | 8.foo | ||||||
|  | 8.bar | ||||||
|  |  | ||||||
							
								
								
									
										43
									
								
								samples/Nit/fibonacci.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								samples/Nit/fibonacci.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2004-2008 Jean Privat <jean@pryen.org> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # A simple exemple of refinement where a method is added to the integer class. | ||||||
|  | module fibonacci | ||||||
|  |  | ||||||
|  | redef class Int | ||||||
|  | 	# Calculate the self-th element of the fibonacci sequence. | ||||||
|  | 	fun fibonacci: Int | ||||||
|  | 	do | ||||||
|  | 		if self < 2 then | ||||||
|  | 			return 1 | ||||||
|  | 		else | ||||||
|  | 			return (self-2).fibonacci + (self-1).fibonacci | ||||||
|  | 		end | ||||||
|  | 	end  | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Print usage and exit. | ||||||
|  | fun usage | ||||||
|  | do | ||||||
|  | 	print "Usage: fibonnaci <integer>"  | ||||||
|  | 	exit 0  | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Main part | ||||||
|  | if args.length != 1 then | ||||||
|  | 	usage | ||||||
|  | end | ||||||
|  | print args.first.to_i.fibonacci | ||||||
							
								
								
									
										1
									
								
								samples/Nit/hello_world.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								samples/Nit/hello_world.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | print "hello world" | ||||||
							
								
								
									
										105
									
								
								samples/Nit/html_page.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								samples/Nit/html_page.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | import html | ||||||
|  |  | ||||||
|  | class NitHomepage | ||||||
|  | 	super HTMLPage | ||||||
|  |  | ||||||
|  | 	redef fun head do | ||||||
|  | 		add("meta").attr("charset", "utf-8") | ||||||
|  | 		add("title").text("Nit") | ||||||
|  | 		add("link").attr("rel", "icon").attr("href", "http://nitlanguage.org/favicon.ico").attr("type", "image/x-icon") | ||||||
|  | 		add("link").attr("rel", "stylesheet").attr("href", "http://nitlanguage.org/style.css").attr("type", "text/css") | ||||||
|  | 		add("link").attr("rel", "stylesheet").attr("href", "http://nitlanguage.org/local.css").attr("type", "text/css") | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun body do | ||||||
|  | 		open("article").add_class("page") | ||||||
|  | 			open("section").add_class("pageheader") | ||||||
|  | 				add_html("<a id='toptitle_first' class='toptitle'>the</a><a id='toptitle_second' class='toptitle' href=''>Nit</a><a id='toptitle_third' class='toptitle' href=''>Programming Language</a>") | ||||||
|  | 				open("header").add_class("header") | ||||||
|  | 					open("div").add_class("topsubtitle") | ||||||
|  | 						add("p").text("A Fun Language for Serious Programming") | ||||||
|  | 					close("div") | ||||||
|  | 				close("header") | ||||||
|  | 			close("section") | ||||||
|  |  | ||||||
|  | 			open("div").attr("id", "pagebody") | ||||||
|  | 				open("section").attr("id", "content") | ||||||
|  | 					add("h1").text("# What is Nit?") | ||||||
|  | 					add("p").text("Nit is an object-oriented programming language. The goal of Nit is to propose a robust statically typed programming language where structure is not a pain.") | ||||||
|  | 					add("p").text("So, what does the famous hello world program look like, in Nit?") | ||||||
|  | 					add_html("<pre><tt><span class='normal'>print </span><span class='string'>'Hello, World!'</span></tt></pre>") | ||||||
|  |  | ||||||
|  | 					add("h1").text("# Feature Highlights") | ||||||
|  | 					add("h2").text("Usability") | ||||||
|  | 					add("p").text("Nit's goal is to be usable by real programmers for real projects") | ||||||
|  |  | ||||||
|  | 					open("ul") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "http://en.wikipedia.org/wiki/KISS_principle").text("KISS principle") | ||||||
|  | 						close("li") | ||||||
|  | 						add("li").text("Script-like language without verbosity nor cryptic statements") | ||||||
|  | 						add("li").text("Painless static types: static typing should help programmers") | ||||||
|  | 						add("li").text("Efficient development, efficient execution, efficient evolution.") | ||||||
|  | 					close("ul") | ||||||
|  |  | ||||||
|  | 					add("h2").text("Robustness") | ||||||
|  | 					add("p").text("Nit will help you to write bug-free programs") | ||||||
|  |  | ||||||
|  | 					open("ul") | ||||||
|  | 						add("li").text("Strong static typing") | ||||||
|  | 						add("li").text("No more NullPointerException") | ||||||
|  | 					close("ul") | ||||||
|  |  | ||||||
|  | 					add("h2").text("Object-Oriented") | ||||||
|  | 					add("p").text("Nit's guideline is to follow the most powerful OO principles") | ||||||
|  |  | ||||||
|  | 					open("ul") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "./everything_is_an_object/").text("Everything is an object") | ||||||
|  | 						close("li") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "./multiple_inheritance/").text("Multiple inheritance") | ||||||
|  | 						close("li") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "./refinement/").text("Open classes") | ||||||
|  | 						close("li") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "./virtual_types/").text("Virtual types") | ||||||
|  | 						close("li") | ||||||
|  | 					close("ul") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 					add("h1").text("# Getting Started") | ||||||
|  | 					add("p").text("Get Nit from its Git repository:") | ||||||
|  |  | ||||||
|  | 					add_html("<pre><code>$ git clone http://nitlanguage.org/nit.git</code></pre>") | ||||||
|  | 					add("p").text("Build the compiler (may be long):") | ||||||
|  | 					add_html("<pre><code>$ cd nit\n") | ||||||
|  | 					add_html("$ make</code></pre>") | ||||||
|  | 					add("p").text("Compile a program:") | ||||||
|  | 					add_html("<pre><code>$ bin/nitc examples/hello_world.nit</code></pre>") | ||||||
|  | 					add("p").text("Execute the program:") | ||||||
|  | 					add_html("<pre><code>$ ./hello_world</code></pre>") | ||||||
|  | 				close("section") | ||||||
|  | 			close("div") | ||||||
|  | 		close("article") | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var page = new NitHomepage | ||||||
|  | page.write_to stdout | ||||||
|  | page.write_to_file("nit.html") | ||||||
							
								
								
									
										100
									
								
								samples/Nit/int_stack.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								samples/Nit/int_stack.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # An example that defines and uses stacks of integers. | ||||||
|  | # The implementation is done with a simple linked list. | ||||||
|  | # It features: free constructors, nullable types and some adaptive typing. | ||||||
|  | module int_stack | ||||||
|  |  | ||||||
|  | # A stack of integer implemented by a simple linked list. | ||||||
|  | # Note that this is only a toy class since a real linked list will gain to use | ||||||
|  | # generics and extends interfaces, like Collection, from the standard library. | ||||||
|  | class IntStack | ||||||
|  | 	# The head node of the list. | ||||||
|  | 	# Null means that the stack is empty. | ||||||
|  | 	private var head: nullable ISNode = null | ||||||
|  |  | ||||||
|  | 	# Add a new integer in the stack. | ||||||
|  | 	fun push(val: Int) | ||||||
|  | 	do | ||||||
|  | 		self.head = new ISNode(val, self.head) | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Remove and return the last pushed integer. | ||||||
|  | 	# Return null if the stack is empty. | ||||||
|  | 	fun pop: nullable Int | ||||||
|  | 	do | ||||||
|  | 		var head = self.head | ||||||
|  | 		if head == null then return null | ||||||
|  | 		# Note: the followings are statically safe because of the | ||||||
|  | 		# previous 'if'. | ||||||
|  | 		var val = head.val | ||||||
|  | 		self.head = head.next | ||||||
|  | 		return val | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Return the sum of all integers of the stack. | ||||||
|  | 	# Return 0 if the stack is empty. | ||||||
|  | 	fun sumall: Int | ||||||
|  | 	do | ||||||
|  | 		var sum = 0 | ||||||
|  | 		var cur = self.head | ||||||
|  | 		while cur != null do | ||||||
|  | 			# Note: the followings are statically safe because of | ||||||
|  | 			# the condition of the 'while'. | ||||||
|  | 			sum += cur.val | ||||||
|  | 			cur = cur.next | ||||||
|  | 		end | ||||||
|  | 		return sum | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Note: Because all attributes have a default value, a free constructor | ||||||
|  | 	# "init()" is implicitly defined. | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # A node of a IntStack | ||||||
|  | private class ISNode | ||||||
|  | 	# The integer value stored in the node. | ||||||
|  | 	var val: Int | ||||||
|  |  | ||||||
|  | 	# The next node, if any. | ||||||
|  | 	var next: nullable ISNode | ||||||
|  |  | ||||||
|  | 	# Note: A free constructor "init(val: Int, next: nullable ISNode)" is | ||||||
|  | 	# implicitly defined. | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var l = new IntStack | ||||||
|  | l.push(1) | ||||||
|  | l.push(2) | ||||||
|  | l.push(3) | ||||||
|  |  | ||||||
|  | print l.sumall | ||||||
|  |  | ||||||
|  | # Note: the 'for' control structure cannot be used on IntStack in its current state. | ||||||
|  | # It requires a more advanced topic. | ||||||
|  | # However, why not using the 'loop' control structure? | ||||||
|  | loop | ||||||
|  | 	var i = l.pop | ||||||
|  | 	if i == null then break | ||||||
|  | 	# The following is statically safe because of the previous 'if'. | ||||||
|  | 	print i * 10 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Note: 'or else' is used to give an alternative of a null expression. | ||||||
|  | l.push(5) | ||||||
|  | print l.pop or else 0 # l.pop gives 5, so print 5 | ||||||
|  | print l.pop or else 0 # l.pop gives null, so print the alternative: 0 | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										193
									
								
								samples/Nit/opengles2_hello_triangle.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								samples/Nit/opengles2_hello_triangle.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Basic example of OpenGL ES 2.0 usage from the book OpenGL ES 2.0 Programming Guide. | ||||||
|  | # | ||||||
|  | # Code reference: | ||||||
|  | # https://code.google.com/p/opengles-book-samples/source/browse/trunk/LinuxX11/Chapter_2/Hello_Triangle/Hello_Triangle.c  | ||||||
|  | module opengles2_hello_triangle | ||||||
|  |  | ||||||
|  | import glesv2 | ||||||
|  | import egl | ||||||
|  | import mnit_linux # for sdl | ||||||
|  | import x11 | ||||||
|  |  | ||||||
|  | if "NIT_TESTING".environ == "true" then exit(0) | ||||||
|  |  | ||||||
|  | var window_width = 800 | ||||||
|  | var window_height = 600 | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## SDL | ||||||
|  | # | ||||||
|  | var sdl_display = new SDLDisplay(window_width, window_height) | ||||||
|  | var sdl_wm_info = new SDLSystemWindowManagerInfo | ||||||
|  | var x11_window_handle = sdl_wm_info.x11_window_handle | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## X11 | ||||||
|  | # | ||||||
|  | var x_display = x_open_default_display | ||||||
|  | assert x_display != 0 else print "x11 fail" | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## EGL | ||||||
|  | # | ||||||
|  | var egl_display = new EGLDisplay(x_display) | ||||||
|  | assert egl_display.is_valid else print "EGL display is not valid" | ||||||
|  | egl_display.initialize | ||||||
|  |  | ||||||
|  | print "EGL version: {egl_display.version}" | ||||||
|  | print "EGL vendor: {egl_display.vendor}" | ||||||
|  | print "EGL extensions: {egl_display.extensions.join(", ")}" | ||||||
|  | print "EGL client APIs: {egl_display.client_apis.join(", ")}" | ||||||
|  |  | ||||||
|  | assert egl_display.is_valid else print egl_display.error | ||||||
|  |  | ||||||
|  | var config_chooser = new EGLConfigChooser | ||||||
|  | #config_chooser.surface_type_egl | ||||||
|  | config_chooser.blue_size = 8 | ||||||
|  | config_chooser.green_size = 8 | ||||||
|  | config_chooser.red_size = 8 | ||||||
|  | #config_chooser.alpha_size = 8 | ||||||
|  | #config_chooser.depth_size = 8 | ||||||
|  | #config_chooser.stencil_size = 8 | ||||||
|  | #config_chooser.sample_buffers = 1 | ||||||
|  | config_chooser.close | ||||||
|  |  | ||||||
|  | var configs = config_chooser.choose(egl_display) | ||||||
|  | assert configs != null else print "choosing config failed: {egl_display.error}" | ||||||
|  | assert not configs.is_empty else print "no EGL config" | ||||||
|  |  | ||||||
|  | print "{configs.length} EGL configs available" | ||||||
|  | for config in configs do | ||||||
|  | 	var attribs = config.attribs(egl_display) | ||||||
|  | 	print "* caveats: {attribs.caveat}" | ||||||
|  | 	print "  conformant to: {attribs.conformant}" | ||||||
|  | 	print "  size of RGBA: {attribs.red_size} {attribs.green_size} {attribs.blue_size} {attribs.alpha_size}" | ||||||
|  | 	print "  buffer, depth, stencil: {attribs.buffer_size} {attribs.depth_size} {attribs.stencil_size}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var config = configs.first | ||||||
|  |  | ||||||
|  | var format = config.attribs(egl_display).native_visual_id | ||||||
|  |  | ||||||
|  | # TODO android part | ||||||
|  | # Opengles1Display_midway_init(recv, format); | ||||||
|  |  | ||||||
|  | var surface = egl_display.create_window_surface(config, x11_window_handle, [0]) | ||||||
|  | assert surface.is_ok else print egl_display.error | ||||||
|  |  | ||||||
|  | var context = egl_display.create_context(config) | ||||||
|  | assert context.is_ok else print egl_display.error | ||||||
|  |  | ||||||
|  | var make_current_res = egl_display.make_current(surface, surface, context) | ||||||
|  | assert make_current_res | ||||||
|  |  | ||||||
|  | var width = surface.attribs(egl_display).width | ||||||
|  | var height = surface.attribs(egl_display).height | ||||||
|  | print "Width: {width}" | ||||||
|  | print "Height: {height}" | ||||||
|  |  | ||||||
|  | assert egl_bind_opengl_es_api else print "eglBingAPI failed: {egl_display.error}" | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## GLESv2 | ||||||
|  | # | ||||||
|  |  | ||||||
|  | print "Can compile shaders? {gl_shader_compiler}" | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | assert gl_shader_compiler else print "Cannot compile shaders" | ||||||
|  |  | ||||||
|  | # gl program | ||||||
|  | print gl_error.to_s | ||||||
|  | var program = new GLProgram | ||||||
|  | if not program.is_ok then | ||||||
|  | 	print "Program is not ok: {gl_error.to_s}\nLog:" | ||||||
|  | 	print program.info_log | ||||||
|  | 	abort | ||||||
|  | end | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | # vertex shader | ||||||
|  | var vertex_shader = new GLVertexShader | ||||||
|  | assert vertex_shader.is_ok else print "Vertex shader is not ok: {gl_error}" | ||||||
|  | vertex_shader.source = """ | ||||||
|  | attribute vec4 vPosition;    | ||||||
|  | void main()                  | ||||||
|  | {                            | ||||||
|  |   gl_Position = vPosition;   | ||||||
|  | }                           """ | ||||||
|  | vertex_shader.compile | ||||||
|  | assert vertex_shader.is_compiled else print "Vertex shader compilation failed with: {vertex_shader.info_log} {program.info_log}" | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | # fragment shader | ||||||
|  | var fragment_shader = new GLFragmentShader | ||||||
|  | assert fragment_shader.is_ok else print "Fragment shader is not ok: {gl_error}" | ||||||
|  | fragment_shader.source = """ | ||||||
|  | precision mediump float; | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  | 	gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); | ||||||
|  | } | ||||||
|  | """ | ||||||
|  | fragment_shader.compile | ||||||
|  | assert fragment_shader.is_compiled else print "Fragment shader compilation failed with: {fragment_shader.info_log}" | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | program.attach_shader vertex_shader | ||||||
|  | program.attach_shader fragment_shader | ||||||
|  | program.bind_attrib_location(0, "vPosition") | ||||||
|  | program.link | ||||||
|  | assert program.is_linked else print "Linking failed: {program.info_log}" | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | # draw! | ||||||
|  | var vertices = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0] | ||||||
|  | var vertex_array = new VertexArray(0, 3, vertices) | ||||||
|  | vertex_array.attrib_pointer | ||||||
|  | gl_clear_color(0.5, 0.0, 0.5, 1.0) | ||||||
|  | for i in [0..10000[ do | ||||||
|  | 	printn "." | ||||||
|  | 	assert_no_gl_error | ||||||
|  | 	gl_viewport(0, 0, width, height) | ||||||
|  | 	gl_clear_color_buffer | ||||||
|  | 	program.use | ||||||
|  | 	vertex_array.enable | ||||||
|  | 	vertex_array.draw_arrays_triangles | ||||||
|  | 	egl_display.swap_buffers(surface) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # delete | ||||||
|  | program.delete | ||||||
|  | vertex_shader.delete | ||||||
|  | fragment_shader.delete | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## EGL | ||||||
|  | # | ||||||
|  | # close | ||||||
|  | egl_display.make_current(new EGLSurface.none, new EGLSurface.none, new EGLContext.none) | ||||||
|  | egl_display.destroy_context(context) | ||||||
|  | egl_display.destroy_surface(surface) | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## SDL | ||||||
|  | # | ||||||
|  | # close | ||||||
|  | sdl_display.destroy | ||||||
							
								
								
									
										22
									
								
								samples/Nit/print_arguments.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								samples/Nit/print_arguments.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2004-2008 Jean Privat <jean@pryen.org> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # How to print arguments of the command line. | ||||||
|  | module print_arguments | ||||||
|  |  | ||||||
|  | for a in args do | ||||||
|  | 	print a | ||||||
|  | end | ||||||
							
								
								
									
										48
									
								
								samples/Nit/procedural_array.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								samples/Nit/procedural_array.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2004-2008 Jean Privat <jean@pryen.org> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # A procedural program (without explicit class definition). | ||||||
|  | # This program manipulates arrays of integers. | ||||||
|  | module procedural_array | ||||||
|  |  | ||||||
|  | # The sum of the elements of `a'. | ||||||
|  | # Uses a 'for' control structure. | ||||||
|  | fun array_sum(a: Array[Int]): Int | ||||||
|  | do | ||||||
|  | 	var sum = 0 | ||||||
|  | 	for i in a do | ||||||
|  | 		sum = sum + i | ||||||
|  | 	end | ||||||
|  | 	return sum | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # The sum of the elements of `a' (alternative version). | ||||||
|  | # Uses a 'while' control structure. | ||||||
|  | fun array_sum_alt(a: Array[Int]): Int | ||||||
|  | do | ||||||
|  | 	var sum = 0 | ||||||
|  | 	var i = 0 | ||||||
|  | 	while i < a.length do | ||||||
|  | 		sum = sum + a[i] | ||||||
|  | 		i = i + 1 | ||||||
|  | 	end | ||||||
|  | 	return sum | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # The main part of the program. | ||||||
|  | var a = [10, 5, 8, 9] | ||||||
|  | print(array_sum(a)) | ||||||
|  | print(array_sum_alt(a)) | ||||||
							
								
								
									
										38
									
								
								samples/Nit/socket_client.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								samples/Nit/socket_client.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Client sample using the Socket module which connect to the server sample. | ||||||
|  | module socket_client | ||||||
|  |  | ||||||
|  | import socket | ||||||
|  |  | ||||||
|  | if args.length < 2 then | ||||||
|  | 	print "Usage : socket_client <host> <port>" | ||||||
|  | 	return | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var s = new Socket.client(args[0], args[1].to_i) | ||||||
|  | print "[HOST ADDRESS] : {s.address}" | ||||||
|  | print "[HOST] : {s.host}" | ||||||
|  | print "[PORT] : {s.port}" | ||||||
|  | print "Connecting ... {s.connected}" | ||||||
|  | if s.connected then | ||||||
|  | 	print "Writing ... Hello server !" | ||||||
|  | 	s.write("Hello server !") | ||||||
|  | 	print "[Response from server] : {s.read(100)}" | ||||||
|  | 	print "Closing ..." | ||||||
|  | 	s.close | ||||||
|  | end | ||||||
							
								
								
									
										52
									
								
								samples/Nit/socket_server.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								samples/Nit/socket_server.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Server sample using the Socket module which allow client to connect | ||||||
|  | module socket_server | ||||||
|  |  | ||||||
|  | import socket | ||||||
|  |  | ||||||
|  | if args.is_empty then | ||||||
|  | 	print "Usage : socket_server <port>" | ||||||
|  | 	return | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var socket = new Socket.server(args[0].to_i, 1) | ||||||
|  | print "[PORT] : {socket.port.to_s}" | ||||||
|  |  | ||||||
|  | var clients = new Array[Socket] | ||||||
|  | var max = socket | ||||||
|  | loop | ||||||
|  | 	var fs = new SocketObserver(true, true, true) | ||||||
|  | 	fs.readset.set(socket) | ||||||
|  |  | ||||||
|  | 	for c in clients do fs.readset.set(c) | ||||||
|  |  | ||||||
|  | 	if fs.select(max, 4, 0) == 0 then | ||||||
|  | 		print "Error occured in select {sys.errno.strerror}" | ||||||
|  | 		break | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	if fs.readset.is_set(socket) then | ||||||
|  | 		var ns = socket.accept | ||||||
|  | 		print "Accepting {ns.address} ... " | ||||||
|  | 		print "[Message from {ns.address}] : {ns.read(100)}" | ||||||
|  | 		ns.write("Goodbye client.") | ||||||
|  | 		print "Closing {ns.address} ..." | ||||||
|  | 		ns.close | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
							
								
								
									
										94
									
								
								samples/Nit/tmpl_composer.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								samples/Nit/tmpl_composer.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | import template | ||||||
|  |  | ||||||
|  | ### Here, definition of the specific templates | ||||||
|  |  | ||||||
|  | # The root template for composers | ||||||
|  | class TmplComposers | ||||||
|  | 	super Template | ||||||
|  |  | ||||||
|  | 	# Short list of composers | ||||||
|  | 	var composers = new Array[TmplComposer] | ||||||
|  |  | ||||||
|  | 	# Detailled list of composers | ||||||
|  | 	var composer_details = new Array[TmplComposerDetail] | ||||||
|  |  | ||||||
|  | 	# Add a composer in both lists | ||||||
|  | 	fun add_composer(firstname, lastname: String, birth, death: Int) | ||||||
|  | 	do | ||||||
|  | 		composers.add(new TmplComposer(lastname)) | ||||||
|  | 		composer_details.add(new TmplComposerDetail(firstname, lastname, birth, death)) | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun rendering do | ||||||
|  | 		add """ | ||||||
|  | COMPOSERS | ||||||
|  | ========= | ||||||
|  | """ | ||||||
|  | 		add_all composers | ||||||
|  | 		add """ | ||||||
|  |  | ||||||
|  | DETAILS | ||||||
|  | ======= | ||||||
|  | """ | ||||||
|  | 		add_all composer_details | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # A composer in the short list of composers | ||||||
|  | class TmplComposer | ||||||
|  | 	super Template | ||||||
|  |  | ||||||
|  | 	# Short name | ||||||
|  | 	var name: String | ||||||
|  |  | ||||||
|  | 	init(name: String) do self.name = name | ||||||
|  |  | ||||||
|  | 	redef fun rendering do add "- {name}\n" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # A composer in the detailled list of composers | ||||||
|  | class TmplComposerDetail | ||||||
|  | 	super Template | ||||||
|  |  | ||||||
|  | 	var firstname: String | ||||||
|  | 	var lastname: String | ||||||
|  | 	var birth: Int | ||||||
|  | 	var death: Int | ||||||
|  |  | ||||||
|  | 	init(firstname, lastname: String, birth, death: Int) do | ||||||
|  | 		self.firstname = firstname | ||||||
|  | 		self.lastname = lastname | ||||||
|  | 		self.birth = birth | ||||||
|  | 		self.death = death | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun rendering do add """ | ||||||
|  |  | ||||||
|  | COMPOSER: {{{firstname}}} {{{lastname}}} | ||||||
|  | BIRTH...: {{{birth}}} | ||||||
|  | DEATH...: {{{death}}} | ||||||
|  | """ | ||||||
|  |  | ||||||
|  | end | ||||||
|  |  | ||||||
|  | ### Here a simple usage of the templates | ||||||
|  |  | ||||||
|  | var f = new TmplComposers | ||||||
|  | f.add_composer("Johann Sebastian", "Bach", 1685, 1750) | ||||||
|  | f.add_composer("George Frideric", "Handel", 1685, 1759) | ||||||
|  | f.add_composer("Wolfgang Amadeus", "Mozart", 1756, 1791) | ||||||
|  | f.write_to(stdout) | ||||||
							
								
								
									
										46
									
								
								samples/Nit/websocket_server.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								samples/Nit/websocket_server.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2014 Lucas Bajolet <r4pass@hotmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Sample module for a minimal chat server using Websockets on port 8088 | ||||||
|  | module websocket_server | ||||||
|  |  | ||||||
|  | import websocket | ||||||
|  |  | ||||||
|  | var sock = new WebSocket(8088, 1) | ||||||
|  |  | ||||||
|  | var msg: String | ||||||
|  |  | ||||||
|  | if sock.listener.eof then | ||||||
|  | 	print sys.errno.strerror | ||||||
|  | end | ||||||
|  |  | ||||||
|  | sock.accept | ||||||
|  |  | ||||||
|  | while not sock.listener.eof do | ||||||
|  | 	if not sock.connected then sock.accept | ||||||
|  | 	if sys.stdin.poll_in then | ||||||
|  | 		msg = gets | ||||||
|  | 		printn "Received message : {msg}" | ||||||
|  | 		if msg == "exit" then sock.close | ||||||
|  | 		if msg == "disconnect" then sock.disconnect_client | ||||||
|  | 		sock.write(msg) | ||||||
|  | 	end | ||||||
|  | 	if sock.can_read(10) then | ||||||
|  | 		msg = sock.read_line | ||||||
|  | 		if msg != "" then print msg | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
							
								
								
									
										80
									
								
								samples/Nix/nginx.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								samples/Nix/nginx.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | |||||||
|  | { stdenv, fetchurl, fetchgit, openssl, zlib, pcre, libxml2, libxslt, expat | ||||||
|  | , rtmp ? false | ||||||
|  | , fullWebDAV ? false | ||||||
|  | , syslog ? false | ||||||
|  | , moreheaders ? false, ...}: | ||||||
|  |  | ||||||
|  | let | ||||||
|  |   version = "1.4.4"; | ||||||
|  |   mainSrc = fetchurl { | ||||||
|  |     url = "http://nginx.org/download/nginx-${version}.tar.gz"; | ||||||
|  |     sha256 = "1f82845mpgmhvm151fhn2cnqjggw9w7cvsqbva9rb320wmc9m63w"; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   rtmp-ext = fetchgit { | ||||||
|  |     url = git://github.com/arut/nginx-rtmp-module.git; | ||||||
|  |     rev = "1cfb7aeb582789f3b15a03da5b662d1811e2a3f1"; | ||||||
|  |     sha256 = "03ikfd2l8mzsjwx896l07rdrw5jn7jjfdiyl572yb9jfrnk48fwi"; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   dav-ext = fetchgit { | ||||||
|  |     url = git://github.com/arut/nginx-dav-ext-module.git; | ||||||
|  |     rev = "54cebc1f21fc13391aae692c6cce672fa7986f9d"; | ||||||
|  |     sha256 = "1dvpq1fg5rslnl05z8jc39sgnvh3akam9qxfl033akpczq1bh8nq"; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   syslog-ext = fetchgit { | ||||||
|  |     url = https://github.com/yaoweibin/nginx_syslog_patch.git; | ||||||
|  |     rev = "165affd9741f0e30c4c8225da5e487d33832aca3"; | ||||||
|  |     sha256 = "14dkkafjnbapp6jnvrjg9ip46j00cr8pqc2g7374z9aj7hrvdvhs"; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   moreheaders-ext = fetchgit { | ||||||
|  |     url = https://github.com/agentzh/headers-more-nginx-module.git; | ||||||
|  |     rev = "refs/tags/v0.23"; | ||||||
|  |     sha256 = "12pbjgsxnvcf2ff2i2qdn39q4cm5czlgrng96j8ml4cgxvnbdh39"; | ||||||
|  |   }; | ||||||
|  | in | ||||||
|  |  | ||||||
|  | stdenv.mkDerivation rec { | ||||||
|  |   name = "nginx-${version}"; | ||||||
|  |   src = mainSrc; | ||||||
|  |  | ||||||
|  |   buildInputs = [ openssl zlib pcre libxml2 libxslt | ||||||
|  |     ] ++ stdenv.lib.optional fullWebDAV expat; | ||||||
|  |  | ||||||
|  |   patches = if syslog then [ "${syslog-ext}/syslog_1.4.0.patch" ] else []; | ||||||
|  |  | ||||||
|  |   configureFlags = [ | ||||||
|  |     "--with-http_ssl_module" | ||||||
|  |     "--with-http_spdy_module" | ||||||
|  |     "--with-http_xslt_module" | ||||||
|  |     "--with-http_sub_module" | ||||||
|  |     "--with-http_dav_module" | ||||||
|  |     "--with-http_gzip_static_module" | ||||||
|  |     "--with-http_secure_link_module" | ||||||
|  |     "--with-ipv6" | ||||||
|  |     # Install destination problems | ||||||
|  |     # "--with-http_perl_module" | ||||||
|  |   ] ++ stdenv.lib.optional rtmp "--add-module=${rtmp-ext}" | ||||||
|  |     ++ stdenv.lib.optional fullWebDAV "--add-module=${dav-ext}" | ||||||
|  |     ++ stdenv.lib.optional syslog "--add-module=${syslog-ext}" | ||||||
|  |     ++ stdenv.lib.optional moreheaders "--add-module=${moreheaders-ext}"; | ||||||
|  |  | ||||||
|  |   preConfigure = '' | ||||||
|  |     export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I${libxml2 }/include/libxml2" | ||||||
|  |   ''; | ||||||
|  |  | ||||||
|  |   # escape example | ||||||
|  |   postInstall = '' | ||||||
|  |     mv $out/sbin $out/bin ''' ''${ | ||||||
|  |    ${ if true then ${ "" } else false } | ||||||
|  |   ''; | ||||||
|  |  | ||||||
|  |   meta = { | ||||||
|  |     description = "A reverse proxy and lightweight webserver"; | ||||||
|  |     maintainers = [ stdenv.lib.maintainers.raskin]; | ||||||
|  |     platforms = stdenv.lib.platforms.all; | ||||||
|  |     inherit version; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								samples/Pike/Error.pmod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								samples/Pike/Error.pmod
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | #pike __REAL_VERSION__ | ||||||
|  |  | ||||||
|  | constant Generic = __builtin.GenericError; | ||||||
|  |  | ||||||
|  | constant Index = __builtin.IndexError; | ||||||
|  |  | ||||||
|  | constant BadArgument = __builtin.BadArgumentError; | ||||||
|  |  | ||||||
|  | constant Math = __builtin.MathError; | ||||||
|  |  | ||||||
|  | constant Resource = __builtin.ResourceError; | ||||||
|  |  | ||||||
|  | constant Permission = __builtin.PermissionError; | ||||||
|  |  | ||||||
|  | constant Decode = __builtin.DecodeError; | ||||||
|  |  | ||||||
|  | constant Cpp = __builtin.CppError; | ||||||
|  |  | ||||||
|  | constant Compilation = __builtin.CompilationError; | ||||||
|  |  | ||||||
|  | constant MasterLoad = __builtin.MasterLoadError; | ||||||
|  |  | ||||||
|  | constant ModuleLoad = __builtin.ModuleLoadError; | ||||||
|  |  | ||||||
|  | //! Returns an Error object for any argument it receives. If the | ||||||
|  | //! argument already is an Error object or is empty, it does nothing. | ||||||
|  | object mkerror(mixed error) | ||||||
|  | { | ||||||
|  |   if (error == UNDEFINED) | ||||||
|  |     return error; | ||||||
|  |   if (objectp(error) && error->is_generic_error) | ||||||
|  |     return error; | ||||||
|  |   if (arrayp(error)) | ||||||
|  |     return Error.Generic(@error); | ||||||
|  |   if (stringp(error)) | ||||||
|  |     return Error.Generic(error); | ||||||
|  |   return Error.Generic(sprintf("%O", error)); | ||||||
|  | } | ||||||
							
								
								
									
										360
									
								
								samples/Pike/FakeFile.pike
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								samples/Pike/FakeFile.pike
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,360 @@ | |||||||
|  | #pike __REAL_VERSION__ | ||||||
|  |  | ||||||
|  | //! A string wrapper that pretends to be a @[Stdio.File] object | ||||||
|  | //! in addition to some features of a @[Stdio.FILE] object. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //! This constant can be used to distinguish a FakeFile object | ||||||
|  | //! from a real @[Stdio.File] object. | ||||||
|  | constant is_fake_file = 1; | ||||||
|  |  | ||||||
|  | protected string data; | ||||||
|  | protected int ptr; | ||||||
|  | protected int(0..1) r; | ||||||
|  | protected int(0..1) w; | ||||||
|  | protected int mtime; | ||||||
|  |  | ||||||
|  | protected function read_cb; | ||||||
|  | protected function read_oob_cb; | ||||||
|  | protected function write_cb; | ||||||
|  | protected function write_oob_cb; | ||||||
|  | protected function close_cb; | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->close()] | ||||||
|  | int close(void|string direction) { | ||||||
|  |   direction = lower_case(direction||"rw"); | ||||||
|  |   int cr = has_value(direction, "r"); | ||||||
|  |   int cw = has_value(direction, "w"); | ||||||
|  |  | ||||||
|  |   if(cr) { | ||||||
|  |     r = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if(cw) { | ||||||
|  |     w = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // FIXME: Close callback | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @decl void create(string data, void|string type, void|int pointer) | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->create()] | ||||||
|  | void create(string _data, void|string type, int|void _ptr) { | ||||||
|  |   if(!_data) error("No data string given to FakeFile.\n"); | ||||||
|  |   data = _data; | ||||||
|  |   ptr = _ptr; | ||||||
|  |   mtime = time(); | ||||||
|  |   if(type) { | ||||||
|  |     type = lower_case(type); | ||||||
|  |     if(has_value(type, "r")) | ||||||
|  |       r = 1; | ||||||
|  |     if(has_value(type, "w")) | ||||||
|  |       w = 1; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |     r = w = 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | protected string make_type_str() { | ||||||
|  |   string type = ""; | ||||||
|  |   if(r) type += "r"; | ||||||
|  |   if(w) type += "w"; | ||||||
|  |   return type; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->dup()] | ||||||
|  | this_program dup() { | ||||||
|  |   return this_program(data, make_type_str(), ptr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! Always returns 0. | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->errno()] | ||||||
|  | int errno() { return 0; } | ||||||
|  |  | ||||||
|  | //! Returns size and the creation time of the string. | ||||||
|  | Stdio.Stat stat() { | ||||||
|  |   Stdio.Stat st = Stdio.Stat(); | ||||||
|  |   st->size = sizeof(data); | ||||||
|  |   st->mtime=st->ctime=mtime; | ||||||
|  |   st->atime=time(); | ||||||
|  |   return st; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->line_iterator()] | ||||||
|  | String.SplitIterator line_iterator(int|void trim) { | ||||||
|  |   if(trim) | ||||||
|  |     return String.SplitIterator( data-"\r", '\n' ); | ||||||
|  |   return String.SplitIterator( data, '\n' ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | protected mixed id; | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_id()] | ||||||
|  | mixed query_id() { return id; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_id()] | ||||||
|  | void set_id(mixed _id) { id = _id; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->read_function()] | ||||||
|  | function(:string) read_function(int nbytes) { | ||||||
|  |   return lambda() { return read(nbytes); }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->peek()] | ||||||
|  | int(-1..1) peek(int|float|void timeout) { | ||||||
|  |   if(!r) return -1; | ||||||
|  |   if(ptr >= sizeof(data)) return 0; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! Always returns 0. | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_address()] | ||||||
|  | string query_address(void|int(0..1) is_local) { return 0; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->read()] | ||||||
|  | string read(void|int(0..) len, void|int(0..1) not_all) { | ||||||
|  |   if(!r) return 0; | ||||||
|  |   if (len < 0) error("Cannot read negative number of characters.\n"); | ||||||
|  |   int start=ptr; | ||||||
|  |   ptr += len; | ||||||
|  |   if(zero_type(len) || ptr>sizeof(data)) | ||||||
|  |     ptr = sizeof(data); | ||||||
|  |  | ||||||
|  |   // FIXME: read callback | ||||||
|  |   return data[start..ptr-1]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.FILE()->gets()] | ||||||
|  | string gets() { | ||||||
|  |   if(!r) return 0; | ||||||
|  |   string ret; | ||||||
|  |   sscanf(data,"%*"+(string)ptr+"s%[^\n]",ret); | ||||||
|  |   if(ret) | ||||||
|  |   { | ||||||
|  |     ptr+=sizeof(ret)+1; | ||||||
|  |     if(ptr>sizeof(data)) | ||||||
|  |     { | ||||||
|  |       ptr=sizeof(data); | ||||||
|  |       if(!sizeof(ret)) | ||||||
|  | 	ret = 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // FIXME: read callback | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.FILE()->getchar()] | ||||||
|  | int getchar() { | ||||||
|  |   if(!r) return 0; | ||||||
|  |   int c; | ||||||
|  |   if(catch(c=data[ptr])) | ||||||
|  |     c=-1; | ||||||
|  |   else | ||||||
|  |     ptr++; | ||||||
|  |  | ||||||
|  |   // FIXME: read callback | ||||||
|  |   return c; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.FILE()->unread()] | ||||||
|  | void unread(string s) { | ||||||
|  |   if(!r) return; | ||||||
|  |   if(data[ptr-sizeof(s)..ptr-1]==s) | ||||||
|  |     ptr-=sizeof(s); | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     data=s+data[ptr..]; | ||||||
|  |     ptr=0; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->seek()] | ||||||
|  | int seek(int pos, void|int mult, void|int add) { | ||||||
|  |   if(mult) | ||||||
|  |     pos = pos*mult+add; | ||||||
|  |   if(pos<0) | ||||||
|  |   { | ||||||
|  |     pos = sizeof(data)+pos; | ||||||
|  |     if( pos < 0 ) | ||||||
|  | 	pos = 0; | ||||||
|  |   } | ||||||
|  |   ptr = pos; | ||||||
|  |   if( ptr > strlen( data ) ) | ||||||
|  |       ptr = strlen(data); | ||||||
|  |   return ptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! Always returns 1. | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->sync()] | ||||||
|  | int(1..1) sync() { return 1; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->tell()] | ||||||
|  | int tell() { return ptr; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->truncate()] | ||||||
|  | int(0..1) truncate(int length) { | ||||||
|  |   data = data[..length-1]; | ||||||
|  |   return sizeof(data)==length; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->write()] | ||||||
|  | int(-1..) write(string|array(string) str, mixed ... extra) { | ||||||
|  |   if(!w) return -1; | ||||||
|  |   if(arrayp(str)) str=str*""; | ||||||
|  |   if(sizeof(extra)) str=sprintf(str, @extra); | ||||||
|  |  | ||||||
|  |   if(ptr==sizeof(data)) { | ||||||
|  |     data += str; | ||||||
|  |     ptr = sizeof(data); | ||||||
|  |   } | ||||||
|  |   else if(sizeof(str)==1) | ||||||
|  |     data[ptr++] = str[0]; | ||||||
|  |   else { | ||||||
|  |     data = data[..ptr-1] + str + data[ptr+sizeof(str)..]; | ||||||
|  |     ptr += sizeof(str); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // FIXME: write callback | ||||||
|  |   return sizeof(str); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_blocking] | ||||||
|  | void set_blocking() { | ||||||
|  |   close_cb = 0; | ||||||
|  |   read_cb = 0; | ||||||
|  |   read_oob_cb = 0; | ||||||
|  |   write_cb = 0; | ||||||
|  |   write_oob_cb = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_blocking_keep_callbacks] | ||||||
|  | void set_blocking_keep_callbacks() { } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_blocking] | ||||||
|  | void set_nonblocking(function rcb, function wcb, function ccb, | ||||||
|  | 		     function rocb, function wocb) { | ||||||
|  |   read_cb = rcb; | ||||||
|  |   write_cb = wcb; | ||||||
|  |   close_cb = ccb; | ||||||
|  |   read_oob_cb = rocb; | ||||||
|  |   write_oob_cb = wocb; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_blocking_keep_callbacks] | ||||||
|  | void set_nonblocking_keep_callbacks() { } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_close_callback] | ||||||
|  | void set_close_callback(function cb) { close_cb = cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_read_callback] | ||||||
|  | void set_read_callback(function cb) { read_cb = cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_read_oob_callback] | ||||||
|  | void set_read_oob_callback(function cb) { read_oob_cb = cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_write_callback] | ||||||
|  | void set_write_callback(function cb) { write_cb = cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_write_oob_callback] | ||||||
|  | void set_write_oob_callback(function cb) { write_oob_cb = cb; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_close_callback] | ||||||
|  | function query_close_callback() { return close_cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_read_callback] | ||||||
|  | function query_read_callback() { return read_cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_read_oob_callback] | ||||||
|  | function query_read_oob_callback() { return read_oob_cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_write_callback] | ||||||
|  | function query_write_callback() { return write_cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_write_oob_callback] | ||||||
|  | function query_write_oob_callback() { return write_oob_cb; } | ||||||
|  |  | ||||||
|  | string _sprintf(int t) { | ||||||
|  |   return t=='O' && sprintf("%O(%d,%O)", this_program, sizeof(data), | ||||||
|  | 			   make_type_str()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // FakeFile specials. | ||||||
|  |  | ||||||
|  | //! A FakeFile can be casted to a string. | ||||||
|  | mixed cast(string to) { | ||||||
|  |   switch(to) { | ||||||
|  |   case "string": return data; | ||||||
|  |   case "object": return this; | ||||||
|  |   } | ||||||
|  |   error("Can not cast object to %O.\n", to); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! Sizeof on a FakeFile returns the size of its contents. | ||||||
|  | int(0..) _sizeof() { | ||||||
|  |   return sizeof(data); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @ignore | ||||||
|  |  | ||||||
|  | #define NOPE(X) mixed X (mixed ... args) { error("This is a FakeFile. %s is not available.\n", #X); } | ||||||
|  | NOPE(assign); | ||||||
|  | NOPE(async_connect); | ||||||
|  | NOPE(connect); | ||||||
|  | NOPE(connect_unix); | ||||||
|  | NOPE(open); | ||||||
|  | NOPE(open_socket); | ||||||
|  | NOPE(pipe); | ||||||
|  | NOPE(tcgetattr); | ||||||
|  | NOPE(tcsetattr); | ||||||
|  |  | ||||||
|  | // Stdio.Fd | ||||||
|  | NOPE(dup2); | ||||||
|  | NOPE(lock); // We could implement this | ||||||
|  | NOPE(mode); // We could implement this | ||||||
|  | NOPE(proxy); // We could implement this | ||||||
|  | NOPE(query_fd); | ||||||
|  | NOPE(read_oob); | ||||||
|  | NOPE(set_close_on_exec); | ||||||
|  | NOPE(set_keepalive); | ||||||
|  | NOPE(trylock); // We could implement this | ||||||
|  | NOPE(write_oob); | ||||||
|  |  | ||||||
|  | //! @endignore | ||||||
							
								
								
									
										260
									
								
								samples/Prolog/format_spec.pl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								samples/Prolog/format_spec.pl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,260 @@ | |||||||
|  | :- module(format_spec, [ format_error/2 | ||||||
|  |                        , format_spec/2 | ||||||
|  |                        , format_spec//1 | ||||||
|  |                        , spec_arity/2 | ||||||
|  |                        , spec_types/2 | ||||||
|  |                        ]). | ||||||
|  |  | ||||||
|  | :- use_module(library(dcg/basics), [eos//0, integer//1, string_without//2]). | ||||||
|  | :- use_module(library(error)). | ||||||
|  | :- use_module(library(when), [when/2]). | ||||||
|  |  | ||||||
|  | % TODO loading this module is optional | ||||||
|  | % TODO it's for my own convenience during development | ||||||
|  | %:- use_module(library(mavis)). | ||||||
|  |  | ||||||
|  | %% format_error(+Goal, -Error:string) is nondet. | ||||||
|  | % | ||||||
|  | %  True if Goal exhibits an Error in its format string. The | ||||||
|  | %  Error string describes what is wrong with Goal. Iterates each | ||||||
|  | %  error on backtracking. | ||||||
|  | % | ||||||
|  | %  Goal may be one of the following predicates: | ||||||
|  | % | ||||||
|  | %    * format/2 | ||||||
|  | %    * format/3 | ||||||
|  | %    * debug/3 | ||||||
|  | format_error(format(Format,Args), Error) :- | ||||||
|  |     format_error_(Format, Args,Error). | ||||||
|  | format_error(format(_,Format,Args), Error) :- | ||||||
|  |     format_error_(Format,Args,Error). | ||||||
|  | format_error(debug(_,Format,Args), Error) :- | ||||||
|  |     format_error_(Format,Args,Error). | ||||||
|  |  | ||||||
|  | format_error_(Format,Args,Error) :- | ||||||
|  |     format_spec(Format, Spec), | ||||||
|  |     !, | ||||||
|  |     is_list(Args), | ||||||
|  |     spec_types(Spec, Types), | ||||||
|  |     types_error(Args, Types, Error). | ||||||
|  | format_error_(Format,_,Error) :- | ||||||
|  |     % \+ format_spec(Format, _), | ||||||
|  |     format(string(Error), "Invalid format string: ~q", [Format]). | ||||||
|  |  | ||||||
|  | types_error(Args, Types, Error) :- | ||||||
|  |     length(Types, TypesLen), | ||||||
|  |     length(Args, ArgsLen), | ||||||
|  |     TypesLen =\= ArgsLen, | ||||||
|  |     !, | ||||||
|  |     format( string(Error) | ||||||
|  |           , "Wrong argument count. Expected ~d, got ~d" | ||||||
|  |           , [TypesLen, ArgsLen] | ||||||
|  |           ). | ||||||
|  | types_error(Args, Types, Error) :- | ||||||
|  |     types_error_(Args, Types, Error). | ||||||
|  |  | ||||||
|  | types_error_([Arg|_],[Type|_],Error) :- | ||||||
|  |     ground(Arg), | ||||||
|  |     \+ is_of_type(Type,Arg), | ||||||
|  |     message_to_string(error(type_error(Type,Arg),_Location),Error). | ||||||
|  | types_error_([_|Args],[_|Types],Error) :- | ||||||
|  |     types_error_(Args, Types, Error). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % check/0 augmentation | ||||||
|  | :- multifile check:checker/2. | ||||||
|  | :- dynamic check:checker/2. | ||||||
|  | check:checker(format_spec:checker, "format/2 strings and arguments"). | ||||||
|  |  | ||||||
|  | :- dynamic format_fail/3. | ||||||
|  |  | ||||||
|  | checker :- | ||||||
|  |     prolog_walk_code([ module_class([user]) | ||||||
|  |                      , infer_meta_predicates(false) | ||||||
|  |                      , autoload(false)  % format/{2,3} are always loaded | ||||||
|  |                      , undefined(ignore) | ||||||
|  |                      , trace_reference(_) | ||||||
|  |                      , on_trace(check_format) | ||||||
|  |                      ]), | ||||||
|  |     retract(format_fail(Goal,Location,Error)), | ||||||
|  |     print_message(warning, format_error(Goal,Location,Error)), | ||||||
|  |     fail.  % iterate all errors | ||||||
|  | checker.  % succeed even if no errors are found | ||||||
|  |  | ||||||
|  | check_format(Module:Goal, _Caller, Location) :- | ||||||
|  |     predicate_property(Module:Goal, imported_from(Source)), | ||||||
|  |     memberchk(Source, [system,prolog_debug]), | ||||||
|  |     can_check(Goal), | ||||||
|  |     format_error(Goal, Error), | ||||||
|  |     assert(format_fail(Goal, Location, Error)), | ||||||
|  |     fail. | ||||||
|  | check_format(_,_,_).  % succeed to avoid printing goals | ||||||
|  |  | ||||||
|  | % true if format_error/2 can check this goal | ||||||
|  | can_check(Goal) :- | ||||||
|  |     once(clause(format_error(Goal,_),_)). | ||||||
|  |  | ||||||
|  | prolog:message(format_error(Goal,Location,Error)) --> | ||||||
|  |     prolog:message_location(Location), | ||||||
|  |     ['~n    In goal: ~q~n    ~s'-[Goal,Error]]. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% format_spec(-Spec)// | ||||||
|  | % | ||||||
|  | %  DCG for parsing format strings. It doesn't yet generate format | ||||||
|  | %  strings from a spec.  See format_spec/2 for details. | ||||||
|  | format_spec([]) --> | ||||||
|  |     eos. | ||||||
|  | format_spec([escape(Numeric,Modifier,Action)|Rest]) --> | ||||||
|  |     "~", | ||||||
|  |     numeric_argument(Numeric), | ||||||
|  |     modifier_argument(Modifier), | ||||||
|  |     action(Action), | ||||||
|  |     format_spec(Rest). | ||||||
|  | format_spec([text(String)|Rest]) --> | ||||||
|  |     { when((ground(String);ground(Codes)),string_codes(String, Codes)) }, | ||||||
|  |     string_without("~", Codes), | ||||||
|  |     { Codes \= [] }, | ||||||
|  |     format_spec(Rest). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% format_spec(+Format, -Spec:list) is semidet. | ||||||
|  | % | ||||||
|  | %  Parse a format string.  Each element of Spec is one of the following: | ||||||
|  | % | ||||||
|  | %    * `text(Text)` - text sent to the output as is | ||||||
|  | %    * `escape(Num,Colon,Action)` - a format escape | ||||||
|  | % | ||||||
|  | %  `Num` represents the optional numeric portion of an esape. `Colon` | ||||||
|  | %  represents the optional colon in an escape. `Action` is an atom | ||||||
|  | %  representing the action to be take by this escape. | ||||||
|  | format_spec(Format, Spec) :- | ||||||
|  |     when((ground(Format);ground(Codes)),text_codes(Format, Codes)), | ||||||
|  |     once(phrase(format_spec(Spec), Codes, [])). | ||||||
|  |  | ||||||
|  | %% spec_arity(+FormatSpec, -Arity:positive_integer) is det. | ||||||
|  | % | ||||||
|  | %  True if FormatSpec requires format/2 to have Arity arguments. | ||||||
|  | spec_arity(Spec, Arity) :- | ||||||
|  |     spec_types(Spec, Types), | ||||||
|  |     length(Types, Arity). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% spec_types(+FormatSpec, -Types:list(type)) is det. | ||||||
|  | % | ||||||
|  | %  True if FormatSpec requires format/2 to have arguments of Types. Each | ||||||
|  | %  value of Types is a type as described by error:has_type/2. This | ||||||
|  | %  notion of types is compatible with library(mavis). | ||||||
|  | spec_types(Spec, Types) :- | ||||||
|  |     phrase(spec_types(Spec), Types). | ||||||
|  |  | ||||||
|  | spec_types([]) --> | ||||||
|  |     []. | ||||||
|  | spec_types([Item|Items]) --> | ||||||
|  |     item_types(Item), | ||||||
|  |     spec_types(Items). | ||||||
|  |  | ||||||
|  | item_types(text(_)) --> | ||||||
|  |     []. | ||||||
|  | item_types(escape(Numeric,_,Action)) --> | ||||||
|  |     numeric_types(Numeric), | ||||||
|  |     action_types(Action). | ||||||
|  |  | ||||||
|  | numeric_types(number(_)) --> | ||||||
|  |     []. | ||||||
|  | numeric_types(character(_)) --> | ||||||
|  |     []. | ||||||
|  | numeric_types(star) --> | ||||||
|  |     [number]. | ||||||
|  | numeric_types(nothing) --> | ||||||
|  |     []. | ||||||
|  |  | ||||||
|  | action_types(Action) --> | ||||||
|  |     { atom_codes(Action, [Code]) }, | ||||||
|  |     { action_types(Code, Types) }, | ||||||
|  |     phrase(Types). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% text_codes(Text:text, Codes:codes). | ||||||
|  | text_codes(Var, Codes) :- | ||||||
|  |     var(Var), | ||||||
|  |     !, | ||||||
|  |     string_codes(Var, Codes). | ||||||
|  | text_codes(Atom, Codes) :- | ||||||
|  |     atom(Atom), | ||||||
|  |     !, | ||||||
|  |     atom_codes(Atom, Codes). | ||||||
|  | text_codes(String, Codes) :- | ||||||
|  |     string(String), | ||||||
|  |     !, | ||||||
|  |     string_codes(String, Codes). | ||||||
|  | text_codes(Codes, Codes) :- | ||||||
|  |     is_of_type(codes, Codes). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | numeric_argument(number(N)) --> | ||||||
|  |     integer(N). | ||||||
|  | numeric_argument(character(C)) --> | ||||||
|  |     "`", | ||||||
|  |     [C]. | ||||||
|  | numeric_argument(star) --> | ||||||
|  |     "*". | ||||||
|  | numeric_argument(nothing) --> | ||||||
|  |     "". | ||||||
|  |  | ||||||
|  |  | ||||||
|  | modifier_argument(colon) --> | ||||||
|  |     ":". | ||||||
|  | modifier_argument(no_colon) --> | ||||||
|  |     \+ ":". | ||||||
|  |  | ||||||
|  |  | ||||||
|  | action(Action) --> | ||||||
|  |     [C], | ||||||
|  |     { is_action(C) }, | ||||||
|  |     { atom_codes(Action, [C]) }. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% is_action(+Action:integer) is semidet. | ||||||
|  | %% is_action(-Action:integer) is multi. | ||||||
|  | % | ||||||
|  | %  True if Action is a valid format/2 action character. Iterates all | ||||||
|  | %  acceptable action characters, if Action is unbound. | ||||||
|  | is_action(Action) :- | ||||||
|  |     action_types(Action, _). | ||||||
|  |  | ||||||
|  | %% action_types(?Action:integer, ?Types:list(type)) | ||||||
|  | % | ||||||
|  | %  True if Action consumes arguments matching Types. An action (like | ||||||
|  | %  `~`), which consumes no arguments, has `Types=[]`.  For example, | ||||||
|  | % | ||||||
|  | %      ?- action_types(0'~, Types). | ||||||
|  | %      Types = []. | ||||||
|  | %      ?- action_types(0'a, Types). | ||||||
|  | %      Types = [atom]. | ||||||
|  | action_types(0'~, []). | ||||||
|  | action_types(0'a, [atom]). | ||||||
|  | action_types(0'c, [integer]).  % specifically, a code | ||||||
|  | action_types(0'd, [integer]). | ||||||
|  | action_types(0'D, [integer]). | ||||||
|  | action_types(0'e, [float]). | ||||||
|  | action_types(0'E, [float]). | ||||||
|  | action_types(0'f, [float]). | ||||||
|  | action_types(0'g, [float]). | ||||||
|  | action_types(0'G, [float]). | ||||||
|  | action_types(0'i, [any]). | ||||||
|  | action_types(0'I, [integer]). | ||||||
|  | action_types(0'k, [any]). | ||||||
|  | action_types(0'n, []). | ||||||
|  | action_types(0'N, []). | ||||||
|  | action_types(0'p, [any]). | ||||||
|  | action_types(0'q, [any]). | ||||||
|  | action_types(0'r, [integer]). | ||||||
|  | action_types(0'R, [integer]). | ||||||
|  | action_types(0's, [text]). | ||||||
|  | action_types(0'@, [callable]). | ||||||
|  | action_types(0't, []). | ||||||
|  | action_types(0'|, []). | ||||||
|  | action_types(0'+, []). | ||||||
|  | action_types(0'w, [any]). | ||||||
|  | action_types(0'W, [any, list]). | ||||||
							
								
								
									
										194
									
								
								samples/Prolog/func.pl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								samples/Prolog/func.pl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | |||||||
|  | :- module(func, [ op(675, xfy, ($)) | ||||||
|  |                 , op(650, xfy, (of)) | ||||||
|  |                 , ($)/2 | ||||||
|  |                 , (of)/2 | ||||||
|  |                 ]). | ||||||
|  | :- use_module(library(list_util), [xfy_list/3]). | ||||||
|  | :- use_module(library(function_expansion)). | ||||||
|  | :- use_module(library(arithmetic)). | ||||||
|  | :- use_module(library(error)). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % true if the module whose terms are being read has specifically | ||||||
|  | % imported library(func). | ||||||
|  | wants_func :- | ||||||
|  |     prolog_load_context(module, Module), | ||||||
|  |     Module \== func,  % we don't want func sugar ourselves | ||||||
|  |     predicate_property(Module:of(_,_),imported_from(func)). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%  compile_function(+Term, -In, -Out, -Goal) is semidet. | ||||||
|  | % | ||||||
|  | %   True if Term represents a function from In to Out | ||||||
|  | %   implemented by calling Goal.  This multifile hook is | ||||||
|  | %   called by $/2 and of/2 to convert a term into a goal. | ||||||
|  | %   It's used at compile time for macro expansion. | ||||||
|  | %   It's used at run time to handle functions which aren't | ||||||
|  | %   known at compile time. | ||||||
|  | %   When called as a hook, Term is guaranteed to be =nonvar=. | ||||||
|  | % | ||||||
|  | %   For example, to treat library(assoc) terms as functions which | ||||||
|  | %   map a key to a value, one might define: | ||||||
|  | % | ||||||
|  | %       :- multifile compile_function/4. | ||||||
|  | %       compile_function(Assoc, Key, Value, Goal) :- | ||||||
|  | %           is_assoc(Assoc), | ||||||
|  | %           Goal = get_assoc(Key, Assoc, Value). | ||||||
|  | % | ||||||
|  | %   Then one could write: | ||||||
|  | % | ||||||
|  | %       list_to_assoc([a-1, b-2, c-3], Assoc), | ||||||
|  | %       Two = Assoc $ b, | ||||||
|  | :- multifile compile_function/4. | ||||||
|  | compile_function(Var, _, _, _) :- | ||||||
|  |     % variables storing functions must be evaluated at run time | ||||||
|  |     % and can't be compiled, a priori, into a goal | ||||||
|  |     var(Var), | ||||||
|  |     !, | ||||||
|  |     fail. | ||||||
|  | compile_function(Expr, In, Out, Out is Expr) :- | ||||||
|  |     % arithmetic expression of one variable are simply evaluated | ||||||
|  |     \+ string(Expr),  % evaluable/1 throws exception with strings | ||||||
|  |     arithmetic:evaluable(Expr), | ||||||
|  |     term_variables(Expr, [In]). | ||||||
|  | compile_function(F, In, Out, func:Goal) :- | ||||||
|  |     % composed functions | ||||||
|  |     function_composition_term(F), | ||||||
|  |     user:function_expansion(F, func:Functor, true), | ||||||
|  |     Goal =.. [Functor,In,Out]. | ||||||
|  | compile_function(F, In, Out, Goal) :- | ||||||
|  |     % string interpolation via format templates | ||||||
|  |     format_template(F), | ||||||
|  |     ( atom(F) -> | ||||||
|  |         Goal = format(atom(Out), F, In) | ||||||
|  |     ; string(F) -> | ||||||
|  |         Goal = format(string(Out), F, In) | ||||||
|  |     ; error:has_type(codes, F) -> | ||||||
|  |         Goal = format(codes(Out), F, In) | ||||||
|  |     ; fail  % to be explicit | ||||||
|  |     ). | ||||||
|  | compile_function(Dict, In, Out, Goal) :- | ||||||
|  |     is_dict(Dict), | ||||||
|  |     Goal = get_dict(In, Dict, Out). | ||||||
|  |  | ||||||
|  | %%	$(+Function, +Argument) is det. | ||||||
|  | % | ||||||
|  | %	Apply Function to an Argument.  A Function is any predicate | ||||||
|  | %	whose final argument generates output and whose penultimate argument | ||||||
|  | %	accepts input. | ||||||
|  | % | ||||||
|  | %	This is realized by expanding function application to chained | ||||||
|  | %	predicate calls at compile time.  Function application itself can | ||||||
|  | %	be chained. | ||||||
|  | % | ||||||
|  | %	== | ||||||
|  | %	Reversed = reverse $ sort $ [c,d,b]. | ||||||
|  | %	== | ||||||
|  | :- meta_predicate $(2,+). | ||||||
|  | $(_,_) :- | ||||||
|  |     throw(error(permission_error(call, predicate, ($)/2), | ||||||
|  |           context(_, '$/2 must be subject to goal expansion'))). | ||||||
|  |  | ||||||
|  | user:function_expansion($(F,X), Y, Goal) :- | ||||||
|  |     wants_func, | ||||||
|  |     ( func:compile_function(F, X, Y, Goal) -> | ||||||
|  |         true | ||||||
|  |     ; var(F) -> Goal =      % defer until run time | ||||||
|  |         ( func:compile_function(F, X, Y, P) -> | ||||||
|  |             call(P) | ||||||
|  |         ; call(F, X, Y) | ||||||
|  |         ) | ||||||
|  |     ; Goal = call(F, X, Y) | ||||||
|  |     ). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%	of(+F, +G) is det. | ||||||
|  | % | ||||||
|  | %	Creates a new function by composing F and G.  The functions are | ||||||
|  | %	composed at compile time to create a new, compiled predicate which | ||||||
|  | %	behaves like a function.  Function composition can be chained. | ||||||
|  | %	Composed functions can also be applied with $/2. | ||||||
|  | % | ||||||
|  | %	== | ||||||
|  | %	Reversed = reverse of sort $ [c,d,b]. | ||||||
|  | %	== | ||||||
|  | :- meta_predicate of(2,2). | ||||||
|  | of(_,_). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%  format_template(Format) is semidet. | ||||||
|  | % | ||||||
|  | %   True if Format is a template string suitable for format/3. | ||||||
|  | %   The current check is very naive and should be improved. | ||||||
|  | format_template(Format) :- | ||||||
|  |     atom(Format), !, | ||||||
|  |     atom_codes(Format, Codes), | ||||||
|  |     format_template(Codes). | ||||||
|  | format_template(Format) :- | ||||||
|  |     string(Format), | ||||||
|  |     !, | ||||||
|  |     string_codes(Format, Codes), | ||||||
|  |     format_template(Codes). | ||||||
|  | format_template(Format) :- | ||||||
|  |     error:has_type(codes, Format), | ||||||
|  |     memberchk(0'~, Format).  % ' fix syntax highlighting | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % True if the argument is a function composition term | ||||||
|  | function_composition_term(of(_,_)). | ||||||
|  |  | ||||||
|  | % Converts a function composition term into a list of functions to compose | ||||||
|  | functions_to_compose(Term, Funcs) :- | ||||||
|  |     functor(Term, Op, 2), | ||||||
|  |     Op = (of), | ||||||
|  |     xfy_list(Op, Term, Funcs). | ||||||
|  |  | ||||||
|  | % Thread a state variable through a list of functions.  This is similar | ||||||
|  | % to a DCG expansion, but much simpler. | ||||||
|  | thread_state([], [], Out, Out). | ||||||
|  | thread_state([F|Funcs], [Goal|Goals], In, Out) :- | ||||||
|  |     ( compile_function(F, In, Tmp, Goal) -> | ||||||
|  |         true | ||||||
|  |     ; var(F) -> | ||||||
|  |         instantiation_error(F) | ||||||
|  |     ; F =.. [Functor|Args], | ||||||
|  |       append(Args, [In, Tmp], NewArgs), | ||||||
|  |       Goal =.. [Functor|NewArgs] | ||||||
|  |     ), | ||||||
|  |     thread_state(Funcs, Goals, Tmp, Out). | ||||||
|  |  | ||||||
|  | user:function_expansion(Term, func:Functor, true) :- | ||||||
|  |     wants_func, | ||||||
|  |     functions_to_compose(Term, Funcs), | ||||||
|  |     debug(func, 'building composed function for: ~w', [Term]), | ||||||
|  |     variant_sha1(Funcs, Sha), | ||||||
|  |     format(atom(Functor), 'composed_function_~w', [Sha]), | ||||||
|  |     debug(func, '  name: ~s', [Functor]), | ||||||
|  |     ( func:current_predicate(Functor/2) -> | ||||||
|  |         debug(func, '  composed predicate already exists', []) | ||||||
|  |     ; true -> | ||||||
|  |         reverse(Funcs, RevFuncs), | ||||||
|  |         thread_state(RevFuncs, Threaded, In, Out), | ||||||
|  |         xfy_list(',', Body, Threaded), | ||||||
|  |         Head =.. [Functor, In, Out], | ||||||
|  |         func:assert(Head :- Body), | ||||||
|  |         func:compile_predicates([Functor/2]) | ||||||
|  |     ). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % support foo(x,~,y) evaluation | ||||||
|  | user:function_expansion(Term, Output, Goal) :- | ||||||
|  |     wants_func, | ||||||
|  |     compound(Term), | ||||||
|  |  | ||||||
|  |     % has a single ~ argument | ||||||
|  |     setof( X | ||||||
|  |          , ( arg(X,Term,Arg), Arg == '~' ) | ||||||
|  |          , [N] | ||||||
|  |          ), | ||||||
|  |  | ||||||
|  |     % replace ~ with a variable | ||||||
|  |     Term =.. [Name|Args0], | ||||||
|  |     nth1(N, Args0, ~, Rest), | ||||||
|  |     nth1(N, Args, Output, Rest), | ||||||
|  |     Goal =.. [Name|Args]. | ||||||
							
								
								
									
										241
									
								
								samples/Python/Cinema4DPythonPlugin.pyp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								samples/Python/Cinema4DPythonPlugin.pyp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,241 @@ | |||||||
|  | # | ||||||
|  | # Cinema 4D Python Plugin Source file | ||||||
|  | # https://github.com/nr-plugins/nr-xpresso-alignment-tools | ||||||
|  | # | ||||||
|  |  | ||||||
|  | # coding: utf-8 | ||||||
|  | # | ||||||
|  | # Copyright (C) 2012, Niklas Rosenstein | ||||||
|  | # Licensed under the GNU General Public License | ||||||
|  | # | ||||||
|  | # XPAT - XPresso Alignment Tools | ||||||
|  | # ============================== | ||||||
|  | # | ||||||
|  | # The XPAT plugin provides tools for aligning nodes in the Cinema 4D | ||||||
|  | # XPresso Editor, improving readability of complex XPresso set-ups | ||||||
|  | # immensively. | ||||||
|  | # | ||||||
|  | # Requirements: | ||||||
|  | # - MAXON Cinema 4D R13+ | ||||||
|  | # - Python `c4dtools` library. Get it from | ||||||
|  | #   http://github.com/NiklasRosenstein/c4dtools | ||||||
|  | # | ||||||
|  | # Author:  Niklas Rosenstein <rosensteinniklas@gmail.com> | ||||||
|  | # Version: 1.1 (01/06/2012) | ||||||
|  |  | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | import json | ||||||
|  | import c4d | ||||||
|  | import c4dtools | ||||||
|  | import itertools | ||||||
|  |  | ||||||
|  | from c4d.modules import graphview as gv | ||||||
|  | from c4dtools.misc import graphnode | ||||||
|  |  | ||||||
|  | res, importer = c4dtools.prepare(__file__, __res__) | ||||||
|  | settings = c4dtools.helpers.Attributor({ | ||||||
|  |     'options_filename': res.file('config.json'), | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | def align_nodes(nodes, mode, spacing): | ||||||
|  |     r""" | ||||||
|  |     Aligns the passed nodes horizontally and apply the minimum spacing | ||||||
|  |     between them. | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     modes = ['horizontal', 'vertical'] | ||||||
|  |     if not nodes: | ||||||
|  |         return | ||||||
|  |     if mode not in modes: | ||||||
|  |         raise ValueError('invalid mode, choices are: ' + ', '.join(modes)) | ||||||
|  |  | ||||||
|  |     get_0 = lambda x: x.x | ||||||
|  |     get_1 = lambda x: x.y | ||||||
|  |     set_0 = lambda x, v: setattr(x, 'x', v) | ||||||
|  |     set_1 = lambda x, v: setattr(x, 'y', v) | ||||||
|  |  | ||||||
|  |     if mode == 'vertical': | ||||||
|  |         get_0, get_1 = get_1, get_0 | ||||||
|  |         set_0, set_1 = set_1, set_0 | ||||||
|  |  | ||||||
|  |     nodes = [graphnode.GraphNode(n) for n in nodes] | ||||||
|  |     nodes.sort(key=lambda n: get_0(n.position)) | ||||||
|  |     midpoint = graphnode.find_nodes_mid(nodes) | ||||||
|  |  | ||||||
|  |     # Apply the spacing between the nodes relative to the coordinate-systems | ||||||
|  |     # origin. We can offset them later because we now the nodes' midpoint | ||||||
|  |     # already. | ||||||
|  |     first_position = nodes[0].position | ||||||
|  |     new_positions = [] | ||||||
|  |     prev_offset = 0 | ||||||
|  |     for node in nodes: | ||||||
|  |         # Compute the relative position of the node. | ||||||
|  |         position = node.position | ||||||
|  |         set_0(position, get_0(position) - get_0(first_position)) | ||||||
|  |  | ||||||
|  |         # Obtain it's size and check if the node needs to be re-placed. | ||||||
|  |         size = node.size | ||||||
|  |         if get_0(position) < prev_offset: | ||||||
|  |             set_0(position, prev_offset) | ||||||
|  |             prev_offset += spacing + get_0(size) | ||||||
|  |         else: | ||||||
|  |             prev_offset = get_0(position) + get_0(size) + spacing | ||||||
|  |  | ||||||
|  |         set_1(position, get_1(midpoint)) | ||||||
|  |         new_positions.append(position) | ||||||
|  |  | ||||||
|  |     # Center the nodes again. | ||||||
|  |     bbox_size = prev_offset - spacing | ||||||
|  |     bbox_size_2 = bbox_size * 0.5 | ||||||
|  |     for node, position in itertools.izip(nodes, new_positions): | ||||||
|  |         # TODO: Here is some issue with offsetting the nodes. Some value | ||||||
|  |         # dependent on the spacing must be added here to not make the nodes | ||||||
|  |         # move horizontally/vertically although they have already been | ||||||
|  |         # aligned. | ||||||
|  |         set_0(position, get_0(midpoint) + get_0(position) - bbox_size_2 + spacing) | ||||||
|  |         node.position = position | ||||||
|  |  | ||||||
|  | def align_nodes_shortcut(mode, spacing): | ||||||
|  |     master = gv.GetMaster(0) | ||||||
|  |     if not master: | ||||||
|  |         return | ||||||
|  |  | ||||||
|  |     root = master.GetRoot() | ||||||
|  |     if not root: | ||||||
|  |         return | ||||||
|  |  | ||||||
|  |     nodes = graphnode.find_selected_nodes(root) | ||||||
|  |     if nodes: | ||||||
|  |         master.AddUndo() | ||||||
|  |         align_nodes(nodes, mode, spacing) | ||||||
|  |         c4d.EventAdd() | ||||||
|  |  | ||||||
|  |     return True | ||||||
|  |  | ||||||
|  | class XPAT_Options(c4dtools.helpers.Attributor): | ||||||
|  |     r""" | ||||||
|  |     This class organizes the options for the XPAT plugin, i.e. | ||||||
|  |     validating, loading and saving. | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     defaults = { | ||||||
|  |         'hspace': 50, | ||||||
|  |         'vspace': 20, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def __init__(self, filename=None): | ||||||
|  |         super(XPAT_Options, self).__init__() | ||||||
|  |         self.load(filename) | ||||||
|  |  | ||||||
|  |     def load(self, filename=None): | ||||||
|  |         r""" | ||||||
|  |         Load the options from file pointed to by filename. If filename | ||||||
|  |         is None, it defaults to the filename defined in options in the | ||||||
|  |         global scope. | ||||||
|  |         """ | ||||||
|  |  | ||||||
|  |         if filename is None: | ||||||
|  |             filename = settings.options_filename | ||||||
|  |  | ||||||
|  |         if os.path.isfile(filename): | ||||||
|  |             self.dict_ = self.defaults.copy() | ||||||
|  |             with open(filename, 'rb') as fp: | ||||||
|  |                 self.dict_.update(json.load(fp)) | ||||||
|  |         else: | ||||||
|  |             self.dict_ = self.defaults.copy() | ||||||
|  |             self.save() | ||||||
|  |  | ||||||
|  |     def save(self, filename=None): | ||||||
|  |         r""" | ||||||
|  |         Save the options defined in XPAT_Options instance to HD. | ||||||
|  |         """ | ||||||
|  |  | ||||||
|  |         if filename is None: | ||||||
|  |             filename = settings.options_filename | ||||||
|  |  | ||||||
|  |         values = dict((k, v) for k, v in self.dict_.iteritems() | ||||||
|  |                       if k in self.defaults) | ||||||
|  |         with open(filename, 'wb') as fp: | ||||||
|  |             json.dump(values, fp) | ||||||
|  |  | ||||||
|  | class XPAT_OptionsDialog(c4d.gui.GeDialog): | ||||||
|  |     r""" | ||||||
|  |     This class implements the behavior of the XPAT options dialog, | ||||||
|  |     taking care of storing the options on the HD and loading them | ||||||
|  |     again on startup. | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     # c4d.gui.GeDialog | ||||||
|  |  | ||||||
|  |     def CreateLayout(self): | ||||||
|  |         return self.LoadDialogResource(res.DLG_OPTIONS) | ||||||
|  |  | ||||||
|  |     def InitValues(self): | ||||||
|  |         self.SetLong(res.EDT_HSPACE, options.hspace) | ||||||
|  |         self.SetLong(res.EDT_VSPACE, options.vspace) | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  |     def Command(self, id, msg): | ||||||
|  |         if id == res.BTN_SAVE: | ||||||
|  |             options.hspace = self.GetLong(res.EDT_HSPACE) | ||||||
|  |             options.vspace = self.GetLong(res.EDT_VSPACE) | ||||||
|  |             options.save() | ||||||
|  |             self.Close() | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  | class XPAT_Command_OpenOptionsDialog(c4dtools.plugins.Command): | ||||||
|  |     r""" | ||||||
|  |     This Cinema 4D CommandData plugin opens the XPAT options dialog | ||||||
|  |     when being executed. | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     def __init__(self): | ||||||
|  |         super(XPAT_Command_OpenOptionsDialog, self).__init__() | ||||||
|  |         self._dialog = None | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def dialog(self): | ||||||
|  |         if not self._dialog: | ||||||
|  |             self._dialog = XPAT_OptionsDialog() | ||||||
|  |         return self._dialog | ||||||
|  |  | ||||||
|  |     # c4dtools.plugins.Command | ||||||
|  |  | ||||||
|  |     PLUGIN_ID = 1029621 | ||||||
|  |     PLUGIN_NAME = res.string.XPAT_COMMAND_OPENOPTIONSDIALOG() | ||||||
|  |     PLUGIN_HELP = res.string.XPAT_COMMAND_OPENOPTIONSDIALOG_HELP() | ||||||
|  |  | ||||||
|  |     # c4d.gui.CommandData | ||||||
|  |  | ||||||
|  |     def Execute(self, doc): | ||||||
|  |         return self.dialog.Open(c4d.DLG_TYPE_MODAL) | ||||||
|  |  | ||||||
|  | class XPAT_Command_AlignHorizontal(c4dtools.plugins.Command): | ||||||
|  |  | ||||||
|  |     PLUGIN_ID = 1029538 | ||||||
|  |     PLUGIN_NAME = res.string.XPAT_COMMAND_ALIGNHORIZONTAL() | ||||||
|  |     PLUGIN_ICON = res.file('xpresso-align-h.png') | ||||||
|  |     PLUGIN_HELP = res.string.XPAT_COMMAND_ALIGNHORIZONTAL_HELP() | ||||||
|  |  | ||||||
|  |     def Execute(self, doc): | ||||||
|  |         align_nodes_shortcut('horizontal', options.hspace) | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  | class XPAT_Command_AlignVertical(c4dtools.plugins.Command): | ||||||
|  |  | ||||||
|  |     PLUGIN_ID = 1029539 | ||||||
|  |     PLUGIN_NAME = res.string.XPAT_COMMAND_ALIGNVERTICAL() | ||||||
|  |     PLUGIN_ICON = res.file('xpresso-align-v.png') | ||||||
|  |     PLUGIN_HELP = res.string.XPAT_COMMAND_ALIGNVERTICAL_HELP() | ||||||
|  |  | ||||||
|  |     def Execute(self, doc): | ||||||
|  |         align_nodes_shortcut('vertical', options.vspace) | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  | options = XPAT_Options() | ||||||
|  |  | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     c4dtools.plugins.main() | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								samples/QMake/complex.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								samples/QMake/complex.pro
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | # This QMake file is complex, as it usese | ||||||
|  | # boolean operators and function calls | ||||||
|  |  | ||||||
|  | QT += core gui | ||||||
|  | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets | ||||||
|  |  | ||||||
|  | # We could use some OpenGL right now | ||||||
|  | contains(QT_CONFIG, opengl) | contains(QT_CONFIG, opengles2) { | ||||||
|  |    QT += opengl | ||||||
|  | } else { | ||||||
|  |    DEFINES += QT_NO_OPENGL | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEMPLATE = app | ||||||
|  | win32 { | ||||||
|  |     TARGET = BlahApp | ||||||
|  |     RC_FILE = Resources/winres.rc | ||||||
|  | } | ||||||
|  | !win32 { TARGET = blahapp } | ||||||
|  |  | ||||||
|  | # Let's add a PRI file! | ||||||
|  | include(functions.pri) | ||||||
|  |  | ||||||
|  | SOURCES += file.cpp | ||||||
|  |  | ||||||
|  | HEADERS  += file.h | ||||||
|  |  | ||||||
|  | FORMS    += file.ui | ||||||
|  |  | ||||||
|  | RESOURCES += res.qrc | ||||||
							
								
								
									
										8
									
								
								samples/QMake/functions.pri
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								samples/QMake/functions.pri
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | # QMake include file that calls some functions | ||||||
|  | # and does nothing else... | ||||||
|  |  | ||||||
|  | exists(.git/HEAD) { | ||||||
|  |     system(git rev-parse HEAD >rev.txt) | ||||||
|  | } else { | ||||||
|  |     system(echo ThisIsNotAGitRepo >rev.txt) | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								samples/QMake/qmake.script!
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								samples/QMake/qmake.script!
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | #!/usr/bin/qmake | ||||||
|  | message(This is QMake.) | ||||||
							
								
								
									
										17
									
								
								samples/QMake/simple.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								samples/QMake/simple.pro
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | # Simple QMake file | ||||||
|  |  | ||||||
|  | CONFIG += qt | ||||||
|  | QT += core gui | ||||||
|  | TEMPLATE = app | ||||||
|  | TARGET = simpleapp | ||||||
|  |  | ||||||
|  | SOURCES += file.cpp \ | ||||||
|  |     file2.c \ | ||||||
|  |     This/Is/Folder/file3.cpp | ||||||
|  |  | ||||||
|  | HEADERS += file.h \ | ||||||
|  |     file2.h \ | ||||||
|  |     This/Is/Folder/file3.h | ||||||
|  |  | ||||||
|  | FORMS += This/Is/Folder/file3.ui \ | ||||||
|  |     Test.ui | ||||||
							
								
								
									
										19
									
								
								samples/Ruby/filenames/.pryrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								samples/Ruby/filenames/.pryrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | Pry.config.commands.import Pry::ExtendedCommands::Experimental | ||||||
|  |  | ||||||
|  | Pry.config.pager = false | ||||||
|  |  | ||||||
|  | Pry.config.color = false | ||||||
|  |  | ||||||
|  | Pry.config.commands.alias_command "lM", "ls -M" | ||||||
|  |  | ||||||
|  | Pry.config.commands.command "add", "Add a list of numbers together" do |*args| | ||||||
|  |   output.puts "Result is: #{args.map(&:to_i).inject(&:+)}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | Pry.config.history.should_save = false | ||||||
|  |  | ||||||
|  | Pry.config.prompt = [proc { "input> " }, | ||||||
|  |                      proc { "     | " }] | ||||||
|  |  | ||||||
|  | # Disable pry-buggy-plug: | ||||||
|  | Pry.plugins["buggy-plug"].disable! | ||||||
							
								
								
									
										28
									
								
								samples/Zephir/filenames/exception.zep.c
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								samples/Zephir/filenames/exception.zep.c
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "../../ext_config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <php.h> | ||||||
|  | #include "../../php_ext.h" | ||||||
|  | #include "../../ext.h" | ||||||
|  |  | ||||||
|  | #include <Zend/zend_operators.h> | ||||||
|  | #include <Zend/zend_exceptions.h> | ||||||
|  | #include <Zend/zend_interfaces.h> | ||||||
|  |  | ||||||
|  | #include "kernel/main.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Test\Router\Exception | ||||||
|  |  * | ||||||
|  |  * Exceptions generated by the router | ||||||
|  |  */ | ||||||
|  | ZEPHIR_INIT_CLASS(Test_Router_Exception) { | ||||||
|  |  | ||||||
|  |     ZEPHIR_REGISTER_CLASS_EX(Test\\Router, Exception, test, router_exception, zend_exception_get_default(TSRMLS_C), NULL, 0); | ||||||
|  |  | ||||||
|  |     return SUCCESS; | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								samples/Zephir/filenames/exception.zep.h
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								samples/Zephir/filenames/exception.zep.h
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  |  | ||||||
|  | extern zend_class_entry *test_router_exception_ce; | ||||||
|  |  | ||||||
|  | ZEPHIR_INIT_CLASS(Test_Router_Exception); | ||||||
							
								
								
									
										8
									
								
								samples/Zephir/filenames/exception.zep.php
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								samples/Zephir/filenames/exception.zep.php
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace Test\Router; | ||||||
|  |  | ||||||
|  | class Exception extends \Exception | ||||||
|  | { | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -140,6 +140,13 @@ class TestBlob < Test::Unit::TestCase | |||||||
|     assert !blob("Perl/script.pl").binary? |     assert !blob("Perl/script.pl").binary? | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   def test_all_binary | ||||||
|  |     Samples.each do |sample| | ||||||
|  |       blob = blob(sample[:path]) | ||||||
|  |       assert ! (blob.likely_binary? || blob.binary?), "#{sample[:path]} is a binary file" | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|   def test_text |   def test_text | ||||||
|     assert blob("Text/README").text? |     assert blob("Text/README").text? | ||||||
|     assert blob("Text/dump.sql").text? |     assert blob("Text/dump.sql").text? | ||||||
| @@ -247,6 +254,13 @@ class TestBlob < Test::Unit::TestCase | |||||||
|     # Generated VCR |     # Generated VCR | ||||||
|     assert blob("YAML/vcr_cassette.yml").generated? |     assert blob("YAML/vcr_cassette.yml").generated? | ||||||
|  |  | ||||||
|  |     # Generated by Zephir | ||||||
|  |     assert blob("Zephir/filenames/exception.zep.c").generated? | ||||||
|  |     assert blob("Zephir/filenames/exception.zep.h").generated? | ||||||
|  |     assert blob("Zephir/filenames/exception.zep.php").generated? | ||||||
|  |     assert !blob("Zephir/Router.zep").generated? | ||||||
|  |  | ||||||
|  |  | ||||||
|     assert Linguist::Generated.generated?("node_modules/grunt/lib/grunt.js", nil) |     assert Linguist::Generated.generated?("node_modules/grunt/lib/grunt.js", nil) | ||||||
|   end |   end | ||||||
|  |  | ||||||
| @@ -271,6 +285,10 @@ class TestBlob < Test::Unit::TestCase | |||||||
|     # 'thirdparty' directory |     # 'thirdparty' directory | ||||||
|     assert blob("thirdparty/lib/main.c").vendored? |     assert blob("thirdparty/lib/main.c").vendored? | ||||||
|  |  | ||||||
|  |     # 'extern(al)' directory | ||||||
|  |     assert blob("extern/util/__init__.py").vendored? | ||||||
|  |     assert blob("external/jquery.min.js").vendored? | ||||||
|  |  | ||||||
|     # C deps |     # C deps | ||||||
|     assert blob("deps/http_parser/http_parser.c").vendored? |     assert blob("deps/http_parser/http_parser.c").vendored? | ||||||
|     assert blob("deps/v8/src/v8.h").vendored? |     assert blob("deps/v8/src/v8.h").vendored? | ||||||
| @@ -375,6 +393,12 @@ class TestBlob < Test::Unit::TestCase | |||||||
|     # NuGet Packages |     # NuGet Packages | ||||||
|     assert blob("packages/Modernizr.2.0.6/Content/Scripts/modernizr-2.0.6-development-only.js").vendored? |     assert blob("packages/Modernizr.2.0.6/Content/Scripts/modernizr-2.0.6-development-only.js").vendored? | ||||||
|  |  | ||||||
|  |     # Normalize | ||||||
|  |     assert blob("some/asset/path/normalize.css").vendored? | ||||||
|  |  | ||||||
|  |     # Cocoapods | ||||||
|  |     assert blob('Pods/blah').vendored? | ||||||
|  |  | ||||||
|     # Html5shiv |     # Html5shiv | ||||||
|     assert blob("Scripts/html5shiv.js").vendored? |     assert blob("Scripts/html5shiv.js").vendored? | ||||||
|     assert blob("Scripts/html5shiv.min.js").vendored? |     assert blob("Scripts/html5shiv.min.js").vendored? | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| require 'linguist/heuristics' | require 'linguist/heuristics' | ||||||
| require 'linguist/language' | require 'linguist/language' | ||||||
| require 'linguist/samples' | require 'linguist/samples' | ||||||
|  | require 'linguist/file_blob' | ||||||
|  |  | ||||||
| require 'test/unit' | require 'test/unit' | ||||||
|  |  | ||||||
| @@ -35,7 +36,8 @@ class TestHeuristcs < Test::Unit::TestCase | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def test_detect_still_works_if_nothing_matches |   def test_detect_still_works_if_nothing_matches | ||||||
|     match = Language.detect("Hello.m", fixture("Objective-C/hello.m")) |     blob = Linguist::FileBlob.new(File.join(samples_path, "Objective-C/hello.m")) | ||||||
|  |     match = Language.detect(blob) | ||||||
|     assert_equal Language["Objective-C"], match |     assert_equal Language["Objective-C"], match | ||||||
|   end |   end | ||||||
|    |    | ||||||
|   | |||||||
| @@ -3,22 +3,24 @@ require 'linguist/repository' | |||||||
| require 'test/unit' | require 'test/unit' | ||||||
|  |  | ||||||
| class TestRepository < Test::Unit::TestCase | class TestRepository < Test::Unit::TestCase | ||||||
|   include Linguist |   def rugged_repository | ||||||
|  |     @rugged ||= Rugged::Repository.new(File.expand_path("../../.git", __FILE__)) | ||||||
|   def repo(base_path) |  | ||||||
|     Repository.from_directory(base_path) |  | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def linguist_repo |   def master_oid | ||||||
|     repo(File.expand_path("../..", __FILE__)) |     'd40b4a33deba710e2f494db357c654fbe5d4b419' | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def linguist_repo(oid = master_oid) | ||||||
|  |     Linguist::Repository.new(rugged_repository, oid) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def test_linguist_language |   def test_linguist_language | ||||||
|     # assert_equal Language['Ruby'], linguist_repo.language |     assert_equal 'Ruby', linguist_repo.language | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def test_linguist_languages |   def test_linguist_languages | ||||||
|     # assert linguist_repo.languages[Language['Ruby']] > 10_000 |     assert linguist_repo.languages['Ruby'] > 10_000 | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def test_linguist_size |   def test_linguist_size | ||||||
| @@ -31,7 +33,18 @@ class TestRepository < Test::Unit::TestCase | |||||||
|     assert linguist_repo.breakdown_by_file["Ruby"].include?("lib/linguist/language.rb") |     assert linguist_repo.breakdown_by_file["Ruby"].include?("lib/linguist/language.rb") | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def test_binary_override |   def test_incremental_stats | ||||||
|     assert_equal repo(File.expand_path("../../samples/Nimrod", __FILE__)).language, Language["Nimrod"] |     old_commit = '3d7364877d6794f6cc2a86b493e893968a597332' | ||||||
|  |     old_repo = linguist_repo(old_commit) | ||||||
|  |  | ||||||
|  |     assert old_repo.languages['Ruby'] > 10_000 | ||||||
|  |     assert old_repo.size > 30_000 | ||||||
|  |  | ||||||
|  |     new_repo = Linguist::Repository.incremental(rugged_repository, master_oid, old_commit, old_repo.cache) | ||||||
|  |  | ||||||
|  |     assert new_repo.languages['Ruby'] > old_repo.languages['Ruby'] | ||||||
|  |     assert new_repo.size > old_repo.size | ||||||
|  |  | ||||||
|  |     assert_equal linguist_repo.cache, new_repo.cache | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user