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:  | ||||
|   - git fetch origin master:master | ||||
|   - git fetch origin v2.0.0:v2.0.0 | ||||
|   - sudo apt-get install libicu-dev -y | ||||
|   - gem update --system 2.1.11 | ||||
| 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. Merge github/linguist PR | ||||
|  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/repository' | ||||
| require 'rugged' | ||||
|  | ||||
| path = ARGV[0] || Dir.pwd | ||||
|  | ||||
| @@ -18,7 +19,8 @@ ARGV.shift | ||||
| breakdown = true if ARGV[0] == "--breakdown" | ||||
|  | ||||
| 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| | ||||
|     percentage = ((size / repo.size.to_f) * 100) | ||||
|     percentage = sprintf '%.2f' % percentage | ||||
|   | ||||
| @@ -17,6 +17,7 @@ Gem::Specification.new do |s| | ||||
|   s.add_dependency 'escape_utils',    '~> 1.0.1' | ||||
|   s.add_dependency 'mime-types',      '~> 1.19' | ||||
|   s.add_dependency 'pygments.rb',     '~> 0.6.0' | ||||
|   s.add_dependency 'rugged',          '~> 0.21.0' | ||||
|  | ||||
|   s.add_development_dependency 'json' | ||||
|   s.add_development_dependency 'mocha' | ||||
|   | ||||
| @@ -313,15 +313,7 @@ module Linguist | ||||
|     # | ||||
|     # Returns a Language or nil if none is detected | ||||
|     def language | ||||
|       return @language if defined? @language | ||||
|  | ||||
|       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) | ||||
|       @language ||= Language.detect(self) | ||||
|     end | ||||
|  | ||||
|     # Internal: Get the lexer of the blob. | ||||
|   | ||||
| @@ -63,7 +63,8 @@ module Linguist | ||||
|         generated_jni_header? || | ||||
|         composer_lock? || | ||||
|         node_modules? || | ||||
|         vcr_cassette? | ||||
|         vcr_cassette? || | ||||
|         generated_by_zephir? | ||||
|     end | ||||
|  | ||||
|     # Internal: Is the blob an XCode project file? | ||||
| @@ -237,6 +238,13 @@ module Linguist | ||||
|       !!name.match(/composer.lock/) | ||||
|     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? | ||||
|     # | ||||
|     # Returns true or false | ||||
|   | ||||
| @@ -92,14 +92,20 @@ module Linguist | ||||
|  | ||||
|     # Public: Detects the Language of the blob. | ||||
|     # | ||||
|     # name - String filename | ||||
|     # data - String blob data. A block also maybe passed in for lazy | ||||
|     #        loading. This behavior is deprecated and you should always | ||||
|     #        pass in a String. | ||||
|     # mode - Optional String mode (defaults to nil) | ||||
|     # blob - an object that includes the Linguist `BlobHelper` interface; | ||||
|     #       see Linguist::LazyBlob and Linguist::FileBlob for examples | ||||
|     # | ||||
|     # 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, | ||||
|       # append a "magic" extension so it can be classified with other | ||||
|       # languages that have shebang scripts. | ||||
| @@ -115,10 +121,10 @@ module Linguist | ||||
|       # extension at all, in the case of extensionless scripts), we need to continue | ||||
|       # our detection work | ||||
|       if possible_languages.length > 1 | ||||
|         data = data.call() if data.respond_to?(:call) | ||||
|         data = blob.data | ||||
|         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 == "" | ||||
|           nil | ||||
|         # Check if there's a shebang line and use that as authoritative | ||||
| @@ -397,7 +403,7 @@ module Linguist | ||||
|     # | ||||
|     # Returns the extensions Array | ||||
|     attr_reader :filenames | ||||
|      | ||||
|  | ||||
|     # Public: Return all possible extensions for language | ||||
|     def all_extensions | ||||
|       (extensions + [primary_extension]).uniq | ||||
|   | ||||
| @@ -89,7 +89,7 @@ Agda: | ||||
|  | ||||
| Alloy: | ||||
|   type: programming  # 'modeling' would be more appropiate | ||||
|   lexer: Text only | ||||
|   lexer: Alloy | ||||
|   color: "#cc5c24" | ||||
|   extensions: | ||||
|   - .als | ||||
| @@ -157,7 +157,6 @@ Assembly: | ||||
|   - nasm | ||||
|   extensions: | ||||
|   - .asm | ||||
|   - .inc | ||||
|  | ||||
| Augeas: | ||||
|   type: programming | ||||
| @@ -222,6 +221,8 @@ BlitzBasic: | ||||
|   - .decls | ||||
|  | ||||
| BlitzMax: | ||||
|   type: programming | ||||
|   color: "#cd6400" | ||||
|   extensions: | ||||
|   - .bmx | ||||
|  | ||||
| @@ -529,15 +530,6 @@ Dart: | ||||
|   extensions: | ||||
|   - .dart | ||||
|  | ||||
| DCPU-16 ASM: | ||||
|   type: programming | ||||
|   lexer: dasm16 | ||||
|   extensions: | ||||
|   - .dasm16 | ||||
|   - .dasm | ||||
|   aliases: | ||||
|   - dasm16 | ||||
|  | ||||
| Diff: | ||||
|   extensions: | ||||
|   - .diff | ||||
| @@ -744,12 +736,14 @@ GLSL: | ||||
|   - .glsl | ||||
|   - .fp | ||||
|   - .frag | ||||
|   - .frg | ||||
|   - .fshader | ||||
|   - .geom | ||||
|   - .glslv | ||||
|   - .gshader | ||||
|   - .shader | ||||
|   - .vert | ||||
|   - .vrx | ||||
|   - .vshader | ||||
|  | ||||
| Genshi: | ||||
| @@ -807,6 +801,12 @@ Gosu: | ||||
|   extensions: | ||||
|   - .gs | ||||
|  | ||||
| Grace: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
|   extensions: | ||||
|   - .grace | ||||
|  | ||||
| Grammatical Framework: | ||||
|   type: programming | ||||
|   lexer: Haskell | ||||
| @@ -941,7 +941,7 @@ Hy: | ||||
|  | ||||
| IDL: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
|   lexer: IDL | ||||
|   color: "#e3592c" | ||||
|   extensions: | ||||
|   - .pro | ||||
| @@ -960,7 +960,7 @@ Inno Setup: | ||||
|  | ||||
| Idris: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
|   lexer: Idris | ||||
|   extensions: | ||||
|   - .idr | ||||
|   - .lidr | ||||
| @@ -1095,6 +1095,8 @@ JavaScript: | ||||
|   - .pac | ||||
|   - .sjs | ||||
|   - .ssjs | ||||
|   - .xsjs | ||||
|   - .xsjslib | ||||
|   filenames: | ||||
|   - Jakefile | ||||
|   interpreters: | ||||
| @@ -1293,6 +1295,8 @@ Mathematica: | ||||
|   type: programming | ||||
|   extensions: | ||||
|   - .mathematica | ||||
|   - .m | ||||
|   - .nb | ||||
|   lexer: Text only | ||||
|  | ||||
| Matlab: | ||||
| @@ -1400,6 +1404,19 @@ Nimrod: | ||||
|   - .nim | ||||
|   - .nimrod | ||||
|  | ||||
| Nit: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
|   color: "#0d8921" | ||||
|   extensions: | ||||
|   - .nit | ||||
|  | ||||
| Nix: | ||||
|   type: programming | ||||
|   lexer: Nix | ||||
|   extensions: | ||||
|   - .nix | ||||
|  | ||||
| Nu: | ||||
|   type: programming | ||||
|   lexer: Scheme | ||||
| @@ -1535,6 +1552,8 @@ PHP: | ||||
|   - .phpt | ||||
|   filenames: | ||||
|   - Phakefile | ||||
|   interpreters: | ||||
|   - php | ||||
|  | ||||
| Pan: | ||||
|   type: programming | ||||
| @@ -1609,7 +1628,7 @@ Perl6: | ||||
| Pike: | ||||
|   type: programming | ||||
|   color: "#066ab2" | ||||
|   lexer: C | ||||
|   lexer: Pike | ||||
|   extensions: | ||||
|   - .pike | ||||
|   - .pmod | ||||
| @@ -1706,6 +1725,7 @@ Python: | ||||
|   - .gyp | ||||
|   - .lmi | ||||
|   - .pyde | ||||
|   - .pyp | ||||
|   - .pyt | ||||
|   - .pyw | ||||
|   - .wsgi | ||||
| @@ -1731,6 +1751,12 @@ QML: | ||||
|   extensions: | ||||
|   - .qml | ||||
|  | ||||
| QMake: | ||||
|   lexer: Text only | ||||
|   extensions: | ||||
|   - .pro | ||||
|   - .pri | ||||
|  | ||||
| R: | ||||
|   type: programming | ||||
|   color: "#198ce7" | ||||
| @@ -1870,13 +1896,17 @@ Ruby: | ||||
|   interpreters: | ||||
|   - ruby | ||||
|   filenames: | ||||
|   - .pryrc | ||||
|   - Appraisals | ||||
|   - Berksfile | ||||
|   - Buildfile | ||||
|   - Gemfile | ||||
|   - Gemfile.lock | ||||
|   - Guardfile | ||||
|   - Jarfile | ||||
|   - Mavenfile | ||||
|   - Podfile | ||||
|   - Puppetfile | ||||
|   - Thorfile | ||||
|   - Vagrantfile | ||||
|   - 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 | ||||
|   # 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 | ||||
|   # the entire project. | ||||
|   class Repository | ||||
|     # Public: Initialize a new Repository from a File directory | ||||
|     # | ||||
|     # base_path - A path String | ||||
|     # | ||||
|     # Returns a Repository | ||||
|     def self.from_directory(base_path) | ||||
|       new Dir["#{base_path}/**/*"]. | ||||
|         select { |f| File.file?(f) }. | ||||
|         map { |path| FileBlob.new(path, base_path) } | ||||
|     attr_reader :repository | ||||
|  | ||||
|     # Public: Create a new Repository based on the stats of | ||||
|     # an existing one | ||||
|     def self.incremental(repo, commit_oid, old_commit_oid, old_stats) | ||||
|       repo = self.new(repo, commit_oid) | ||||
|       repo.load_existing_stats(old_commit_oid, old_stats) | ||||
|       repo | ||||
|     end | ||||
|  | ||||
|     # Public: Initialize a new Repository | ||||
|     # Public: Initialize a new Repository to be analyzed for language | ||||
|     # data | ||||
|     # | ||||
|     # enum - Enumerator that responds to `each` and | ||||
|     #        yields Blob objects | ||||
|     # repo - a Rugged::Repository object | ||||
|     # commit_oid - the sha1 of the commit that will be analyzed; | ||||
|     #              this is usually the master branch | ||||
|     # | ||||
|     # Returns a Repository | ||||
|     def initialize(enum) | ||||
|       @enum = enum | ||||
|       @computed_stats = false | ||||
|       @language = @size = nil | ||||
|       @sizes = Hash.new { 0 } | ||||
|       @file_breakdown = Hash.new { |h,k| h[k] = Array.new } | ||||
|     def initialize(repo, commit_oid) | ||||
|       @repository = repo | ||||
|       @commit_oid = commit_oid | ||||
|  | ||||
|       raise TypeError, 'commit_oid must be a commit SHA1' unless commit_oid.is_a?(String) | ||||
|     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 | ||||
|  | ||||
|     # Public: Returns a breakdown of language stats. | ||||
|     # | ||||
|     # Examples | ||||
|     # | ||||
|     #   # => { Language['Ruby'] => 46319, | ||||
|     #          Language['JavaScript'] => 258 } | ||||
|     #   # => { 'Ruby' => 46319, | ||||
|     #          'JavaScript' => 258 } | ||||
|     # | ||||
|     # Returns a Hash of Language keys and Integer size values. | ||||
|     # Returns a Hash of language names and Integer size values. | ||||
|     def languages | ||||
|       compute_stats | ||||
|       @sizes | ||||
|       @sizes ||= begin | ||||
|         sizes = Hash.new { 0 } | ||||
|         cache.each do |_, (language, size)| | ||||
|           sizes[language] += size | ||||
|         end | ||||
|         sizes | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     # Public: Get primary Language of repository. | ||||
|     # | ||||
|     # Returns a Language | ||||
|     # Returns a language name | ||||
|     def language | ||||
|       compute_stats | ||||
|       @language | ||||
|       @language ||= begin | ||||
|         primary = languages.max_by { |(_, size)| size } | ||||
|         primary && primary[0] | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     # Public: Get the total size of the repository. | ||||
|     # | ||||
|     # Returns a byte size Integer | ||||
|     def size | ||||
|       compute_stats | ||||
|       @size | ||||
|       @size ||= languages.inject(0) { |s,(_,v)| s + v } | ||||
|     end | ||||
|  | ||||
|     # Public: Return the language breakdown of this repository by file | ||||
|     # | ||||
|     # Returns a map of language names => [filenames...] | ||||
|     def breakdown_by_file | ||||
|       compute_stats | ||||
|       @file_breakdown | ||||
|       @file_breakdown ||= begin | ||||
|         breakdown = Hash.new { |h,k| h[k] = Array.new } | ||||
|         cache.each do |filename, (language, _)| | ||||
|           breakdown[language] << filename | ||||
|         end | ||||
|         breakdown | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     # Internal: Compute language breakdown for each blob in the Repository. | ||||
|     # Public: Return the cached results of the analysis | ||||
|     # | ||||
|     # Returns nothing | ||||
|     def compute_stats | ||||
|       return if @computed_stats | ||||
|     # This is a per-file breakdown that can be passed to other instances | ||||
|     # of Linguist::Repository to perform incremental scans | ||||
|     # | ||||
|     # 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| | ||||
|         # Skip files that are likely binary | ||||
|         next if blob.likely_binary? | ||||
|     protected | ||||
|     def compute_stats(old_commit_oid, commit_oid, cache = nil) | ||||
|       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 | ||||
|  | ||||
|         # Skip vendored or generated blobs | ||||
|         next if blob.vendored? || blob.generated? || blob.language.nil? | ||||
|       diff = Rugged::Tree.diff(repository, old_tree, new_tree) | ||||
|  | ||||
|         # Only include programming languages and acceptable markup languages | ||||
|         if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name) | ||||
|       diff.each_delta do |delta| | ||||
|         old = delta.old_file[:path] | ||||
|         new = delta.new_file[:path] | ||||
|  | ||||
|           # Build up the per-file breakdown stats | ||||
|           @file_breakdown[blob.language.group.name] << blob.name | ||||
|         file_map.delete(old) | ||||
|         next if delta.binary | ||||
|  | ||||
|           @sizes[blob.language.group] += blob.size | ||||
|         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 | ||||
|           next if blob.vendored? || blob.generated? || blob.language.nil? | ||||
|  | ||||
|           # Only include programming languages and acceptable markup languages | ||||
|           if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name) | ||||
|             file_map[new] = [blob.language.group.name, blob.size] | ||||
|           end | ||||
|         end | ||||
|       end | ||||
|  | ||||
|       # Compute total size | ||||
|       @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 | ||||
|       file_map | ||||
|     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. | ||||
|     def self.each(&block) | ||||
|       Dir.entries(ROOT).each do |category| | ||||
|       Dir.entries(ROOT).sort!.each do |category| | ||||
|         next if category == '.' || category == '..' | ||||
|  | ||||
|         # Skip text and binary for now | ||||
|   | ||||
| @@ -40,9 +40,13 @@ | ||||
| - foundation.min.css | ||||
| - foundation.css | ||||
|  | ||||
| # Normalize.css | ||||
| - normalize.css | ||||
|  | ||||
| # Vendored dependencies | ||||
| - thirdparty/ | ||||
| - vendors?/ | ||||
| - extern(al)?/ | ||||
|  | ||||
| # Debian packaging | ||||
| - ^debian/ | ||||
| @@ -124,6 +128,9 @@ | ||||
|  | ||||
| ## Obj-C ## | ||||
|  | ||||
| # Cocoapods | ||||
| - ^Pods/ | ||||
|  | ||||
| # Sparkle | ||||
| - (^|/)Sparkle/ | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| module Linguist | ||||
|   VERSION = "2.12.0" | ||||
|   VERSION = "3.0.3" | ||||
| 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? | ||||
|   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 | ||||
|     assert blob("Text/README").text? | ||||
|     assert blob("Text/dump.sql").text? | ||||
| @@ -247,6 +254,13 @@ class TestBlob < Test::Unit::TestCase | ||||
|     # Generated VCR | ||||
|     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) | ||||
|   end | ||||
|  | ||||
| @@ -271,6 +285,10 @@ class TestBlob < Test::Unit::TestCase | ||||
|     # 'thirdparty' directory | ||||
|     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 | ||||
|     assert blob("deps/http_parser/http_parser.c").vendored? | ||||
|     assert blob("deps/v8/src/v8.h").vendored? | ||||
| @@ -375,6 +393,12 @@ class TestBlob < Test::Unit::TestCase | ||||
|     # NuGet Packages | ||||
|     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 | ||||
|     assert blob("Scripts/html5shiv.js").vendored? | ||||
|     assert blob("Scripts/html5shiv.min.js").vendored? | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| require 'linguist/heuristics' | ||||
| require 'linguist/language' | ||||
| require 'linguist/samples' | ||||
| require 'linguist/file_blob' | ||||
|  | ||||
| require 'test/unit' | ||||
|  | ||||
| @@ -35,7 +36,8 @@ class TestHeuristcs < Test::Unit::TestCase | ||||
|   end | ||||
|  | ||||
|   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 | ||||
|   end | ||||
|    | ||||
|   | ||||
| @@ -3,22 +3,24 @@ require 'linguist/repository' | ||||
| require 'test/unit' | ||||
|  | ||||
| class TestRepository < Test::Unit::TestCase | ||||
|   include Linguist | ||||
|  | ||||
|   def repo(base_path) | ||||
|     Repository.from_directory(base_path) | ||||
|   def rugged_repository | ||||
|     @rugged ||= Rugged::Repository.new(File.expand_path("../../.git", __FILE__)) | ||||
|   end | ||||
|  | ||||
|   def linguist_repo | ||||
|     repo(File.expand_path("../..", __FILE__)) | ||||
|   def master_oid | ||||
|     'd40b4a33deba710e2f494db357c654fbe5d4b419' | ||||
|   end | ||||
|  | ||||
|   def linguist_repo(oid = master_oid) | ||||
|     Linguist::Repository.new(rugged_repository, oid) | ||||
|   end | ||||
|  | ||||
|   def test_linguist_language | ||||
|     # assert_equal Language['Ruby'], linguist_repo.language | ||||
|     assert_equal 'Ruby', linguist_repo.language | ||||
|   end | ||||
|  | ||||
|   def test_linguist_languages | ||||
|     # assert linguist_repo.languages[Language['Ruby']] > 10_000 | ||||
|     assert linguist_repo.languages['Ruby'] > 10_000 | ||||
|   end | ||||
|  | ||||
|   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") | ||||
|   end | ||||
|  | ||||
|   def test_binary_override | ||||
|     assert_equal repo(File.expand_path("../../samples/Nimrod", __FILE__)).language, Language["Nimrod"] | ||||
|   def test_incremental_stats | ||||
|     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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user